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

时间:2015-05-21 22:16:44

标签: javascript node.js ecmascript-intl

我尝试将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全局变量没有被替换?

2 个答案:

答案 0 :(得分:1)

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

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

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

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

篡改全球范围通常会导致比其值得更多的头痛,最好保持您的包装自包含。您可以在需要的文件中要求填充:

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()));

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

答案 1 :(得分:0)

事实证明,只替换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获得了这些信息。