Angular 6 - i18n vs. ngx-translate

2019-03-24 01:25发布

问题:

I am working on a large project using angular 6. This project needs significant i18n integration. I am trying to make the right decision as to how to proceed.

The way I see it is that I can choose between:

  1. ngx-translate (https://github.com/ngx-translate/core)
  2. Angular i18n (https://angular.io/guide/i18n)

I am leaning toward choosing option 2; Angular's i18n. This is because it is Angular's own built in package and that just sits better with me. Apparently it is also better for SEO and marginally better for performance without any work around. Also, now it is released I think ngx-translate might be deprecated. Lot's of info here: Angular 5 internationalization.

However here are my reservations:

  • Apparently Angular's version is quite new / still catching up (https://github.com/ngx-translate/core/issues/495). Is it too new to take on?
  • Apparently I have to have a separate website build for each language (https://angular.io/guide/i18n#template-translations)??? I really don't think that would be a good thing. Is that right? or is it a case that template files are dynamically inserted each time? I know that with ngx-translate the translated words are just stored in .json files - I like the neatness of that. I don't think we want a bunch of different website builds.

Is there a way to do live language switching with angular i18n? i.e. switching language on the page without reloading / refetching data from the server? Is that what they call JIT?

Has Anyone tried https://github.com/robisim74/angular-l10n? looks very good also.

Many thanks. Best regards.

回答1:

Is it too new to take on?

This is opinion-based, and thus off-topic

Apparently I have to have a separate website

You need a separate application (i.e. index.html + bundles). But you could serve all those applications from a single URL, deciding which one to serve on the server. That will (hopefully) change with Angular 7, when the new dynamic i18n, built on top of Ivy, is available.

is it a case that template files are dynamically inserted each time?

Not sure what you mean. The translations of the locale you build for are stored in the generated template classes at compile time, by the Angular AOT compiler.

Is there a way to do live language switching with angular i18n?

No, and that won't be possible with the next version of i18n either. The same, unique application will be able to run in several languages, but the language will still have to be chosen at startup, and you'll have to restart the app to choose another language.

Is there a way to do live language switching with angular i18n?

No. Not efficiently at least.

Is that what they call JIT?

No. The JIT compiler is what compiles your HTML templates into JavaScript at startup, in the browser. In production, you use the AOT compiler (which is also used to integrate the translations into the generated JS classes), which does a similar compilation of the templates, but at build time rather than runtime.



回答2:

The discussion is still on, and here you can find some answers and opinions, even directly from the Angular developers: https://github.com/ngx-translate/core/issues/495

Personally, I would structure the app with the official i18n and eventually add some dedicated translation in the code with the ngx-translate library.

Is there a way to do live language switching with angular i18n?

Actaully, there is. You need to build different dist of your app, but then you can switch live after the full deploy:

Official Angluar docs and suggested tutorial



回答3:

It is understandable why developers like an ngx-translate like library to take care of internationalization. After all it makes our lives so easy by making the translation problem a 1v1 mapping. Unfortunately this is not how it works with human languages. One has two know more than one language to better understand the shortcomings of this approach.

Here's a little example: Say you have an app for travel expense, you have a tabular view in which one column title is "times" indicating when the expense was reported. Then imagine in such app you have a mini calculator for doing basic verification of your expenses which happens to have a multiplication button x with a layover saying "times". When you do ngx-translate you extract them both with the same key "TIMES" which in turn the translator guy gives you back one translation for. But the first occurrence of "time" is not necessarily translated the same as the second one in all the other languages. Take Spanish for instance:

  • "two TIMES three"(as in the calculator) -> "dos POR tres"
  • "expense TIMES"(as in tabular view) -> "TIEMPOS de gasto"

This is actually why internationalization is moving to the direction of using a more sophisticated format such as XLF to support for meaning, description(in the case of Angular) rather the old 1-depth JSON style which cannot accommodate for translation with respect to context.

Now you may argue that this is solvable by registering two different keys for "times" which in English they happen to map to the same thing but that requires you as a developer to know all the languages your app supports while developing or you would have to go through another iteration(time is money!) of getting customer's feedback and then adding a separate key whereas if you provide description and meaning for your message(text) then the translator takes care of it for you without you having any knowledge of the other language(If you know Spanish think about how complicated this can be with subjunctive and indicative forms of verb which are the same in English but not Spanish).

To answer your other question "Is there a way to do live language switching with angular i18n?": yes there is. Have a look at this awesome article about state management in apps. Long story short you need to have your client and persistent states reflected in URL. Then all you need to do is to add a locale prefix to your path which causes your web server giving you the right locale build. Then whatever your app state was before changing locale change action happened is recoverable from URL(since it "reflects both the persistent and client state").



回答4:

One of the great advantage of Angular I18N is that its affect to templates is minimal. You only have to add i18n attribute on each element you want to localize. So

<p>Hello World<p>

becomes

<p i18n>Hello World<p>

No need to change the markup a lot and no need to manually maintain the resource file. If you use any other I18N library for Angular or React you need to modify you markup a lot such as

<p>Translate("Hello World")<p>

and you have to manually add the string into the neutral resource file such as

"Hello World": "Hello World"

Then if you want to change the string you also have to remember to update the key and value in the resource file.

With Angular I18N you use extract tool to create and maintain the neutral resource files.

What is currently missing in Angular I18N is the ability to localize string in source code. However this feature will appear soon.