【问题标题】:ReferenceError: Intl is not defined in Node.jsReferenceError: Intl 未在 Node.js 中定义
【发布时间】:2013-11-21 15:50:32
【问题描述】:

我正在尝试在 Node.js 中构造一个 new Intl.Collator() 对象。

有谁知道为什么 Intl 对象不会出现在 Node 运行时中?

According to MDN,它被 ECMAScript 指定为命名空间,所以我不明白为什么它不会在那里。

【问题讨论】:

  • 因为该模块未捆绑在 Node 中:P
  • 为什么不呢?不是捆绑在 V8 中的吗?
  • 显然不是。因为var Intl = require('Intl'); 不起作用,new Intl.Collator() 也不起作用

标签: javascript node.js internationalization


【解决方案1】:

不幸的是,当前节点(截至 0.10 版,在撰写本文时)不支持 ECMA-402 Intl 对象,除非您执行节点的自定义编译,这在 node.js Readme 中有记录。

有了 libicu i18n 支持:

svn checkout --force --revision 214189 \
   http://src.chromium.org/svn/trunk/deps/third_party/icu46 \
   deps/v8/third_party/icu46
./configure --with-icu-path=deps/v8/third_party/icu46/icu.gyp
make

进行安装

如果编译一个自定义的 node 构建不是一个选项,或者这个想法让你感到恐惧,一个解决方法是使用 intl module,这是一个涵盖大部分 EMCA-402 的 Javascript 填充标准,Intl.Collator 除外,其原因在项目自述文件中有说明。

使用该模块很简单:

npm install intl --save

然后在你的节点代码中:

var Intl = require('intl');
console.log(new Intl.NumberFormat("de-DE").format(12345678));

希望这会有所帮助。

【讨论】:

【解决方案2】:

由于 io.js 被合并到 Node 中,应该可以在较新版本的 Node 中使用 Intl(在 v3.1.0 的 io.js 中可用)。

  • intl:使用 small-icu 的 Intl 支持现在在构建 (Steven R. Loomis) #2264 中默认启用。
    • String#normalize() 现在可用于 unicode 规范化。
    • Intl 对象以及各种 String 和 Number 方法都存在,但仅支持英语语言环境。
    • 为了支持所有语言环境,必须使用full-icu 构建节点。

https://github.com/nodejs/node/blob/master/CHANGELOG.md#2015-08-18-version-310-fishrock123

【讨论】:

    【解决方案3】:

    Node 0.12 已包含对 Intl 的支持,但它仅附带 ICU 语言环境的一个子集(即:英语)。您需要为完整的 ICU(或您需要的任何子集)构建带有标志的节点。在此处构建 ICU 的详细说明:https://github.com/nodejs/node/wiki/Intl

    我建议阅读 FormatJS 文档: http://formatjs.io/

    尤其是 Intl Polyfill

    https://github.com/andyearnshaw/Intl.js

    var areIntlLocalesSupported = require('intl-locales-supported');
    
    var localesMyAppSupports = [
        /* list locales here */
    ];
    
    if (global.Intl) {
        // Determine if the built-in `Intl` has the locale data we need.
        if (!areIntlLocalesSupported(localesMyAppSupports)) {
            // `Intl` exists, but it doesn't have the data we need, so load the
            // polyfill and replace the constructors we need with the polyfill's.
            require('intl');
            Intl.NumberFormat   = IntlPolyfill.NumberFormat;
            Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;
        }
    } else {
        // No `Intl`, so use and load the polyfill.
        global.Intl = require('intl');
    }
    

    Intl.js 没有(也永远不会)实现 Intl.Collat​​or。对于这一点,您确实需要依赖使用所需语言环境构建的 Node 0.12。

    【讨论】:

    • 更新:full-icu 模块将安装完整数据,请参阅 full-icu#3460
    • 添加是否保存?: Number.prototype.toLocaleString = function(locale) { return Intl.NumberFormat(locale).format(this); }; Date.prototype.toLocaleString = function(locale) { return Intl.DateTimeFormat(locale).format(this); };
    • 对于支持Intl 的标准Node 0.12+ 版本,任何格式都只适用于预先构建的有限语言环境。如果您想要所有语言环境,则需要使用full-icu 构建 Node。我不会弄乱原型,因为你会覆盖标准行为。