Angular i18n - I don't like it

Working with Angular lately I can't help but be disappointed with their i18n implementation.

The Angular approach is that you should tag your strings which need localization with a particular directive which gets stripped out when the code is compiled. So far, so good. Then, you run a CLI tool which scans the code and dumps them into a single messages file (yes, some of this is configurable, but ultimately doesn't fix the root problems so not diving deeper). This is an ouch. And then you're expected to create locale specific versions of this file. Now it really starts to hurt. And then build which produces as many variants of the site as you have configuration locales. DAMN!

I hate this. So I go do some reading and find a video from the Angular team describing the i18n and some of the rationale. Turns out that the believe that localization is not a "tree shakable" problem. Which, according to them means (paraphrased); "when you start the application you cannot know what strings the user needs so you need to load everything".

If all of your localization tokens are in a single, unstructured file... then sure. But whose fault is it that all of the tokens have been dumped into a single unstructured file? Oh right, you created the problem in the first place. There is absolutely no inherent reason. In fact, your solution highlights EXACTLY why it isn't an inherent problem.

So now you've compiled all of the strings directly into the website. Does this mean that the second the user logs in that the application has now indirectly loaded ALL of localized values? Absolutely not. Angular tends load pages and components in a modular fashion. Which is to say, "on-demand". Now, you might ask; "hey, if I can load components on demand, why can't I load my localization on demand as well?". Of course, I don't know why the Angular team built this the way that they did, but I can tell you that it is absolutely technically possible.

The question then becomes; does it matter?

I would say that it does matter. I have no issues with opinionated libraries and frameworks. It promotes consistency and that aspect of opinionated frameworks and libraries is a plus. The opinions enforced though, still need to be able to stand up to the typical use case. If i18m were not the "default option" I don't think it would still be kicking around because, in my opinion, it only works well in very specific use cases. For all others it either breaks down completely or requires massive process considerations to make it work.

To make my point; as a developer, when I make a code change I want to check it in, queue it up testing and be done with it. Note: I may need to do some documentation or other side work as a part of the process before closing out a case sending it the next step, and this is where I would normally want to handle globalization considerations as well. 

With i18n, this is where things start getting messy. When I'm done my code change I need to regenerate the messages file. And then what? I think the straightforward answer would be diff the file against the one I started with, and find the differences. I'll come back to that in a second. After I have the differences I need to send them off for translation (only an idiot would leave translation in the hands of random devs). Then I need to wait for ALL of the translations to come back. Then I need to merge those translations into each of the language files (what could go wrong) then run the build which will generate a locale specific site for each language. And, once again I'll circle back to this in a moment.

Back to send the files for translation. Remember the bit where I said that developers aren't good at translating? Well, translators often aren't good at parsing XML or JSON. So, that diff we have... we need to turn that into something the translation team can deal with. And once they're done we need to take what they've produced and convert it back into something the i18n system can read. JOY! That doesn't seem like a complicated and potentially "fraught with human errors" problem at all. Oh wait it does? Yeah I thought so.

And so you've finally figured that all out with processes? Now we need to test each language individually on each build. 

Wait... what? Well sure, you could just wash your hands of this and push to production but each language is actually running physically different code! And yes, the odds of a runtime error caused by localization are astronomically small, but the translations are now compiled into the site, so even a typographical error would require a re-deployment. Which, due to the above process would likely take more time than you'd like. What if a typo resulted in some cultural offence? Or a misplaced bit of punction ended up promising something you couldn't deliver? Language bugs can be just as serious as functional ones.

Now, you COULD use Angular's runtime localization option, but as described in their video, because they don't believe in modular localization, you have to load everything upfront which might be a deal breaker for a larger site or web application which may contain several MBs of localized text.

I'm done harping on this. Some basic tooling to assist in managing versioned language files might open up the current implementation to a larger audience. Architecturally however, I think that there are simply more use cases where this won't work than ones where it will. Unless you have a small, fairly static site or your application is composed of very small MFEs (in which case you've technically hacked in modularization anyway) then this likely isn't for you.

Personally, I want to be able to structure and group my localizations and load them as needed from a single consistent code-base. There is less code emitted to be tested and the localization can then come from an external service allowing me to decouple most of the localization from the development process while also providing a means of live updating the translations in the event of an issue.

Your company still needs to implement a lot of the same practices, but aside from isolating new/changed keys, development is mostly decoupled from the translation process (as it should be... in my opinion).

Comments

Popular Posts