formatjs/formatjs-site

Fallback for Node.js v0.12

okuryu opened this issue · 9 comments

You know Node.js v0.12 supports Intl object finally, but it support only English language as default. I think that it means there are cases of it doesn't works as expected on the way to fallback as follows which we are suggested.

http://formatjs.io/guide/#intljs

if (!global.Intl) {
    global.Intl = require('intl');
}

Maybe we should simply detect environments based on the version of Node.js, but I see if there are better ways of doing things. What do you think?

Incidentally, we need to update the section in our guide for server side.
http://formatjs.io/guide/#server-side

Yeah, we need to look at this asap. /cc @ericf

If you're using Node 0.12 and you only need English, then I think we can recommended using the built-in. What happens when an app needs more than English, should we format English using the built-in and other locales using the polyfill, or always suggest that the polyfill be used in that case?

If you're using Node 0.12 and you only need English, then I think we can recommended using the built-in.

Yes! I agree.

What happens when an app needs more than English, should we format English using the built-in and other locales using the polyfill, or always suggest that the polyfill be used in that case?

I think it's better to use the polyfill for now, because build-in and polyfill aren't necessarily the same behavior.

I've hit this issue when trying to add Node 0.12 env to Handlebars Intl's Travis CI config:
https://travis-ci.org/yahoo/handlebars-intl/jobs/53758308

There doesn't appear to be a solid way to detecting whether or not the locale you need is actually supported. I tried the following Node 0.12:

Intl.NumberFormat.supportedLocalesOf(['en-AU']);
// => [ 'en-AU' ]

var nf = new Intl.NumberFormat('en-AU', {
    style: 'currency',
    currency: 'USD',
});

nf.format(1);
// => $1

nf.resolvedOptions();
// => { locale: 'en', ...}

Whereas in Firefox, you get the expected result:

nf.format(1);
// => US$1.00

nf.resolvedOptions();
// => { locale: 'en-AU', ...}

So this means that Node 0.12 is a bad state for being able to detect whether or not something is supported, "luckily" this issue is only in English locales, since Node 0.12 returns the expected result in this case:

Intl.NumberFormat.supportedLocalesOf(['zh']);
// => []

I think what needs to change is that Node ships with locale data for all English locales, not just en, since the runtime will incorrectly fallback to en. The other option would be to fix supportedLocalesOf() so that it's more accurate in what it returns.

/cc @srl295

@ericf node or v8? what does chrome do?
edit also, on Firefox && nodejs with 'German' support:

Intl.NumberFormat.supportedLocalesOf(['de-XK']);
// => ['de-XK']

.. which by the above token is unexpected as well.

edit also process.config.variables.icu_small indicates whether a reduced locale set is present.

@srl295 re: de-XK, good point!
Also! I just found this: process.config.variables.icu_locales

console.log(process.config.variables.icu_locales);
// => "en,root"

So this is the data we need, the question is how stable this "API" is for accessing this ICU information.

@caridy notice root above ;)

@ericf yeah, I knew that was the next question when I mentioned that! Technically it's just an input to the .gyp file. Anyways the notion of which locales are actually supported is complex. I will have to dig into the supportedLocalesOf() code, it does seem wrong on both v8 and ff at this point.

@srl295 so it's seeming that our guidance should be:

  1. If you only need to support en, use the built-in.
  2. If you've built Node or are providing your locale data, then use the built-in.
  3. If you can't answer true and be sure for either 1 or 2, then use the polyfill.

And using the polyfill becomes more complex in that the dev will have to specially override the built-ins since the polyfill will see Intl as an object and noop.