globalizejs / globalize

A JavaScript library for internationalization and localization that leverages the official Unicode CLDR JSON data
https://globalizejs.com
MIT License
4.8k stars 603 forks source link

When compiled for production, `Globalize.locale()` returns string #621

Open unindented opened 8 years ago

unindented commented 8 years ago

If you add a console.log(Globalize.locale()) in the app-npm-webpack example app (for example here https://github.com/jquery/globalize/blob/c6cd869fd5a6518eab0595503be85b6b29a7b43f/examples/app-npm-webpack/app/index.js#L3), you get different results in development and production.

In development you get a Cldr instance:

Cldr {ee: EventEmitter, attributes: Object, locale: "en"}

In production you only get a string:

en

I'm getting bitten by this in my own app (where I need to access the attributes field of the Cldr instance), and wanted to verify that the example app had the same problem.

@rxaviers what's your take? Am I missing something?

rxaviers commented 8 years ago

The point of pre-compiling the formatters (and parsers) for production is to allow for faster and smaller code as put by Compilation and the Runtime modules:

Take advantage of compiling your formatters and/or parsers during build time when deploying to production. It's much faster than generating them in real-time and it's also much smaller (i.e., better loading performance).

Your compiled formatters and parsers allow you to skip a big part of the library and also allow you to skip loading CLDR data, because they have already been created (see Performance above for more information).

That means Globalize code for production lacks (on purpose) any code/data that deals with CLDR. Note that CLDR (code and data) has already been used (by the precompilation) to generate the ready-to-be-executed formatters (for production).

rxaviers commented 8 years ago

Having said that, we definitely should improve the documentation for locale() to make what you obverse clear.

rxaviers commented 8 years ago

Please, give me an example on you usage of locale() and I perhaps I have any suggestion.

unindented commented 8 years ago

Understood.

I'm trying to determine whether a language is RTL. I want users to be able to change locale at runtime, without page reload. For me, that includes both calling Globalize.locale(newLocale), and also setting the lang and dir attributes on the html tag of the page.

As you suggested, I was using cldr-data/scriptMetadata.json to determine whether a locale is RTL, and I was relying on cldr.attributes.script. If that data is not available at runtime, I'm not sure how to achieve this...

I have a simplified example project set up: https://github.com/unindented/ts-react-redux-webpack-example

unindented commented 8 years ago

The relevant lines are here: https://github.com/unindented/ts-react-redux-webpack-example/blob/9158c6156fc18cfb4eb82c1a895afb02ddfa8d20/utils/locale/src/index.ts#L55-L78

rxaviers commented 8 years ago

I'll look into your code and example when I have more time, but a quick response for now is that you have two options in your case.

You can use the full Globalize version (not the runtime/compiled one) and keep using anything cldr-related in your app. It's less efficient. You don't need to deal with the globalize-compiler, but you have to handle loading cldr data yourself.

You can use the Globalize runtime version by using globalize-compiler directly. The app-npm-webpack is very handy&easy to use if your app is served at one locale per request. You should be able to get globalize-compiler to compile your formatters in all locales you want your app to support and it would be generated one single compiled file that gives your app support for all these locales simultanously. About the RTL part, by using require('cldr-data/scriptMetadata.json') directly, webpack will bundle that JSON in your app for you (if you happen to use json loader). Therefore, you can access the JSON object itself in your compiled app.

I hope that helps for now, I may reply with more accurate suggestions if I happen to find time to look into your code.

unindented commented 8 years ago

Yeah, I'm certainly going with the second option. The only problem is that, in order to use cldr-data/scriptMetadata.json, I need to know the script of a locale (Latn, Hebr, etc.), and I don't know how to access that information once the cldr.attributes fields have been stripped away.