node.js - full-ICU 在传递 --icu-data-dir Node 选项时有效,但在使用 NODE_ICU_DATA 环境变量时无效

标签 node.js docker alpine-linux icu

情况

我有一个运行我的应用程序的 Alpine/NodeJS Docker 镜像(Alpine Linux 3.11、nodeJS v12.15.0),并且我最近需要在此应用程序中国际化货币。

我注意到我的容器缺少语言环境,因此我需要安装full-ICU。因此,我修改了基于 Alpine 的 Docker 镜像,添加两行来安装 full-ICU:

RUN npm i -g full-icu
ENV NODE_ICU_DATA=“/home/node/.npm/lib/node_modules/full-icu”

安装很顺利,控制台输出如下:

Step 10/15 : RUN npm i -g full-icu
 ---> Running in b14d826c8689
/home/node/.npm/bin/node-full-icu-path -> /home/node/.npm/lib/node_modules/full-icu/node-icu-data.js

> <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="781e0d141455111b0d3849564b5649" rel="noreferrer noopener nofollow">[email protected]</a> postinstall /home/node/.npm/lib/node_modules/full-icu
> node postinstall.js

npm install icu4c-data@64l (Node 12.15.0 and small-icu 64.2) -> icudt64l.dat
full-icu$ /usr/bin/node /home/node/.npm/lib/node_modules/npm/bin/npm-cli.js install icu4c-data@64l
+ <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="026b617736612f6663766342322c34362c30" rel="noreferrer noopener nofollow">[email protected]</a>
added 1 package from 1 contributor in 62.073s
 √ icudt64l.dat (link)
Node will use this ICU datafile if the environment variable NODE_ICU_DATA is set to “/home/node/.npm/lib/node_modules/full-icu”
or with node --icu-data-dir=/home/node/.npm/lib/node_modules/full-icu YOURAPP.js
 For package.json:
{"scripts":{"start":"node --icu-data-dir=/home/node/.npm/lib/node_modules/full-icu YOURAPP.js"}}

By the way, if you have full data, running this in node:
> new Intl.DateTimeFormat('es',{month:'long'}).format(new Date(9E8));
... will show “enero”. If it shows “January” you don't have full data.
News: Please see https://github.com/icu-project/full-icu-npm/issues/6
+ <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1274677e7e3f7b716752233c213c23" rel="noreferrer noopener nofollow">[email protected]</a>
added 1 package from 1 contributor in 63.276s

看起来不错,它识别了我的 NodeJS 版本,没有错误。我可以检查并看到 ICU 数据文件位于正确的位置。

问题

但是,当在该容器内打开 shell(运行 docker run -ti myimage sh )并使用 Intl 时,我注意到仅当使用 --icu-data-dir 运行 Node 时,区域设置才能正常工作 选项,而不是使用 NODE_ICU_DATA 环境变量时。 然而,出于各种原因,我肯定更喜欢环境变量,所以我希望它能够工作。

到目前为止的测试

这是我对 node 的测试:


node --icu-data-dir=/home/node/.npm/lib/node_modules/full-icu

Welcome to Node.js v12.15.0.
Type ".help" for more information.
> new Intl.DateTimeFormat('es',{month:'long'}).format(new Date(9E8));
'enero'

它说的是“enero”,所以它正在工作。这意味着 full-ICU 已正确安装且可访问。


export NODE_ICU_DATA=“/home/node/.npm/lib/node_modules/full-icu” node

Welcome to Node.js v12.15.0.
Type ".help" for more information.
> new Intl.DateTimeFormat('es',{month:'long'}).format(new Date(9E8));
'January'

它不关心我的环境变量(还尝试将环境变量放入 Dockerfile 中,如上所示)


env NODE_ICU_DATA=“/home/node/.npm/lib/node_modules/full-icu” node

Welcome to Node.js v12.15.0.
Type ".help" for more information.
> new Intl.DateTimeFormat('es',{month:'long'}).format(new Date(9E8));
'January'

它也不关心环境变量何时内联。


我也尝试过 .js顺便说一下脚本,不仅仅是NodeJS控制台,还有各种传递环境变量的方式。

为了确定,我尝试安装系统 ICU 软件包,其中 RUN apk --update add --no-cache icu icu-libs icu-dev .

所以...

有人知道为什么在环境变量中指定路径不起作用以及我应该检查什么吗?

最佳答案

我在使用 Plesk 的 VPS 上也遇到同样的问题。 我无法更新 Node 版本,安装的 Node 版本是 v12.4.0。

就我而言,我无法将 full-icu 安装为全局模块,并且进程管理器启动我的应用程序而不运行 package.json 中的启动脚本。

在这种情况下,对我来说,加载完整 icu 支持的唯一方法是使用环境变量。

我首先通过命令行尝试:

export NODE_ICU_DATA=/full/path/of/my/app/node_modules/full-icu

然后

-bash-4.2$ /opt/plesk/node/12/bin/node
Welcome to Node.js v12.4.0.
Type ".help" for more information.
> new Intl.DateTimeFormat('it',{month:'long'}).format(new Date(9E8));
'gennaio'
>

效果很好。

如果我在应用程序的根文件夹中运行此命令,它也可以工作:

NODE_ICU_DATA=node_modules/full-icu /opt/plesk/node/12/bin/node

所以我在应用程序 Node 设置上添加了 ENV var(在 Plesk 中)

NODE_ICU_DATA

有一个值

node_modules/full-icu

重新启动应用程序,i18n 支持即可正常工作。

我希望这可以帮助其他和我有同样情况的人。

关于node.js - full-ICU 在传递 --icu-data-dir Node 选项时有效,但在使用 NODE_ICU_DATA 环境变量时无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65403546/

相关文章:

docker - 在 docker 容器内运行时找不到 Sendmail 主机

docker - Alpine 上哪个库包含 cdefs.h?

javascript - 使用 node.js 将前 100 个质数写入文件

javascript - 如何使用 node.js 在 html 中包含静态文件

javascript - Nodejs - SolrClient,如何等待响应

YAML 中的 docker-compose.yml 破折号语法

jquery - 在express服务器上使用jquery发布json

docker - 通过网络链接的外部容器的别名

docker - Boot2Docke初始化: boot2docker init error in run: Failed to initialize machine "boot2docker-vm": exit status 1

docker - 在 docker alpine 上安装软件包时无法满足的约束