Reputation: 3254
I have an Alpine/NodeJS Docker image running my app (Alpine Linux 3.11, nodeJS v12.15.0), and I recently needed to internationalize currencies in this app.
I noticed that my container was missing locales, so I needed to install full-ICU. Consequently I modified my Alpine-based Docker image to add two lines to install full-ICU:
RUN npm i -g full-icu
ENV NODE_ICU_DATA=“/home/node/.npm/lib/node_modules/full-icu”
The installation went smoothly, the console output said:
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
> [email protected] 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
+ [email protected]
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
+ [email protected]
added 1 package from 1 contributor in 63.276s
It seems fine, it recognized my NodeJS version, there were no errors. I could check and see that the ICU data files were at the right place.
But when opening a shell inside this container (running docker run -ti myimage sh
), and playing with Intl, I noticed that the locales were working properly only when running node with the --icu-data-dir option, not when using the NODE_ICU_DATA environment variable.
However, my preference definitely goes to the environment variable, for various reasons, so I would have liked it to work.
Here are my tests with 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'
It's saying "enero", so it's working. It means that full-ICU is properly installed and reachable.
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'
It doesn't care about my environment variable (also tried putting the environment variable in the Dockerfile, as shown above)
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'
It also doesn't care when the environment variable is inlined.
I also tried with .js
scripts by the way, not just the NodeJS console, and also various ways to pass the environment variable.
And just to be sure, I tried to install system ICU packages, with RUN apk --update add --no-cache icu icu-libs icu-dev
.
Would anyone have an idea about the reason why specifying the path in an environment variable doesn't work, and what I should check?
Upvotes: 2
Views: 4032
Reputation: 2394
I have the same issue with on a VPS with Plesk. I can't update the Node version and the installed Node version is the, v12.4.0.
In my case I can't also install full-icu as global module, and the process manager start my app without run the start script in the package.json.
In this situation for me, the only way for load the full-icu support is to use the environment vars.
I tried first via command line:
export NODE_ICU_DATA=/full/path/of/my/app/node_modules/full-icu
and then
-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'
>
it works fine.
It works too if I run this command in the root folder of my app:
NODE_ICU_DATA=node_modules/full-icu /opt/plesk/node/12/bin/node
So I added an ENV var on the app node setting (in Plesk)
NODE_ICU_DATA
with a value
node_modules/full-icu
Restarting the app the i18n support rightly works.
I hope this could help others people there are in my same situation.
Upvotes: 2
Reputation: 3254
For anyone falling on this issue: the problem was version-specific.
Deploying a more recent NodeJS version fixed these ICU bugs.
Upvotes: 0