节点:无法替换 Intl 以使用 IntlPolyfill

Node: Cannot replace Intl to use IntlPolyfill

我正在尝试将 Intl 与 pt-BR 语言环境一起使用,但我无法使其与 Node 0.12 一起使用。

代码:

global.Intl = require('intl/Intl');
require('intl/locale-data/jsonp/pt-BR.js');

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new Intl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

此代码输出:

May, 2015

我希望是:'Maio, 2015'。

然后,如果我决定创建一个新变量,一切正常:

工作代码:

global.NewIntl = require('intl/Intl');
require('intl/locale-data/jsonp/pt-BR.js');

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new NewIntl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

这会打印出期望值。 问题:为什么Intl全局变量没有被替换?

因为全局对象的Intl 属性不是writable(在Node 0.12.2上测试):

console.log(Object.getOwnPropertyDescriptor(global, 'Intl'));
/*
{ value: {},
  writable: false,
  enumerable: false,
  configurable: false }
*/

将您的代码放在 strict mode 中,它会在尝试分配给不可写属性而不是静默失败时抛出更具描述性的错误。

它也是不可配置的,因此无法完全替换(重新分配)global.Intl。这是一件好事:其他模块和依赖项可能取决于内置 Intl 实现。

篡改全局范围通常会导致比其价值更令人头疼的事情,最好让您的包保持独立。您可以只在需要的文件中要求 polyfill:

var Intl = require('intl/Intl');
// Note: you only need to require the locale once
require('intl/locale-data/jsonp/pt-BR.js');

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new Intl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

然后您可以在需要 Intl 的文件中添加 var Intl = require('intl/Intl');

事实证明,仅替换 DateTimeFormat 和 NumberFormat 即可解决问题:

require('intl/Intl');
require('intl/locale-data/jsonp/pt-BR.js');
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new Intl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

请确保在加载前加载此脚本 react-intl 以防您也使用它。

我从 here 那里得到了这些信息。