Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best practices for using globalize and Node.js with express #460

Open
dpolivy opened this issue Jul 9, 2015 · 7 comments
Open

Best practices for using globalize and Node.js with express #460

dpolivy opened this issue Jul 9, 2015 · 7 comments

Comments

@dpolivy
Copy link

dpolivy commented Jul 9, 2015

The documentation isn't super clear on this, so I was hoping to get a little clarification/confirmation on the recommended best practices for scenarios using globalize within a node.js app powered by express.

Consider the scenario where an app supports multiple locales, and needs to assign the correct one to each incoming request based on the user's chosen preference. For efficiency, it seems like the best approach is to simply create one Globalize object for each supported locale, and then attach that locale-specific instance to the req object for the request, so it's available for use throughout the various codepaths handling the request. I'm trying to avoid the overhead of having to load data for each new request, utilizing too much memory loading duplicate data (e.g., in multiple instances) and to minimize the amount of work that needs to be done when a request comes in.

Is the right way to do this something like the following?

var Globalize = require('globalize');

// Load the correct i18n content
Globalize.load(
    require('cldr/main/en/currencies.json'),
    require('cldr/main/en/ca-gregorian.json'),
    require('cldr/main/en/dateFields.json'),
    require('cldr/main/en/numbers.json'),
    require('cldr/main/en/timeZoneNames.json'),

    require('cldr/main/fr/currencies.json'),
    require('cldr/main/fr/ca-gregorian.json'),
    require('cldr/main/fr/dateFields.json'),
    require('cldr/main/fr/numbers.json'),
    require('cldr/main/fr/timeZoneNames.json'),

    // Repeat above blocks for each locale we want to support
    // ...

    require('cldr/supplemental/currencyData.json'),
    require('cldr/supplemental/likelySubtags.json'),
    require('cldr/supplemental/numberingSystems.json'),
    require('cldr/supplemental/ordinals.json'),
    require('cldr/supplemental/plurals.json'),
    require('cldr/supplemental/timeData.json'),
    require('cldr/supplemental/weekData.json')
);

var en = new Globalize("en");
var fr = new Globalize("fr");
// ... repeat for each locale we want to support

Or, is it better/possible to create the Globalize objects for each locale, and then load the locale-specific CLDR files into just that instance?

Is it necessary to call Globalize.locale() in this scenario to set a global default locale, or is that only required if one is using the global object, vs individual instances?

All of the examples I've seen only seem to show loading a single locale at a time, so perhaps expanding the docs to discuss this scenario would be helpful for others as well.

@dpolivy
Copy link
Author

dpolivy commented Jul 9, 2015

And to add to this question, what's the right way to map from a list of supported "locales" to their proper CLDR JSON files? e.g., if my app supports "en-US", "zh-TW", "fr-FR" -- what's the recommended (automatic) way to map those to the correct CLDR files to pass to load()?

@rxaviers
Copy link
Member

Hi @dpolivy, although we've been discussing this in other places (e.g., rxaviers/cldrjs#30), I haven't replied to this issue directly... Improving our documentation with best practices and better examples is of our interest. We're working towards it and all help is very much appreciated.

For efficiency, it seems like the best approach is to simply create one Globalize object for each supported locale

For optimal performance, you should cache your formatters and parsers per locale.

I'm trying to avoid the overhead of having to load data for each new request,

utilizing too much memory loading duplicate data (e.g., in multiple instances)

The CLDR data you load via Globalize.load() is never duplicated. The JSON is extended with unique data, but never duplicated. The formatters and parsers access this shared data when they are created (e.g., var formatter = Globalize("en").numberFormatter()).

The generated formatters and parsers keep its own copy of processed CLDR data (properties). So, var formatter1 = Globalize("en").numberFormatter() and var formatter2 = Globalize("en").numberFormatter() will obviously waste memory with duplicate properties. So, a rule of thumb is to avoid creating duplicate formatters or parsers and instead to cache them (for example, by re-using formatter created above).

Or, is it better/possible to create the Globalize objects for each locale, and then load the locale-specific CLDR files into just that instance?

The data loaded by Globalize.load() is globally accessible and unique for all instances. When you create an instance, it's assumed that any required CLDR data for such instance has been already loaded.

Is it necessary to call Globalize.locale() in this scenario to set a global default locale, or is that only required if one is using the global object, vs individual instances?

You can either use the instances or the static methods (that requires setting the global locale using Globalize.locale()). So, nope. You can use either one.

And to add to this question, what's the right way to map from a list of supported "locales" to their proper CLDR JSON files? e.g., if my app supports "en-US", "zh-TW", "fr-FR" -- what's the recommended (automatic) way to map those to the correct CLDR files to pass to load()?

Globalize should have improved docs and examples to answer to this question. But for now, anyone can find details in the conversation we're having at rxaviers/cldrjs#30 (comment).

Please, just let me know if you still have any questions.

Do you have any suggestion on how we could improve our docs? Thanks

@rxaviers
Copy link
Member

@dpolivy please could you review #435 solution provided by @devangnegandhi? (note devangnegandhi/globalize-express#1)

@siddo420
Copy link

+1
thanks for the library and effort you guys put into it but documentation is poor

2 or 3 tutorials with simple and slighlty more complicated workflows/use-cases would work for many/most people

@rxaviers
Copy link
Member

Thank you @siddo420. It would be awesome if you could help us to improve documentation. Would you like to submit a PR with the tutorials? I can help in any questions with the library for that. Thanks.

@siddo420
Copy link

Due to time constraints, I've started looking at FormatJS now.

If I am not satisfied with FormatJS, I'll come back and look at the details here again and ask any questions for tutorials.

Thanks rxaviers

@rxaviers
Copy link
Member

Take your time and you're welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants