Situation
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
> full-icu@1.3.1 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
+ icu4c-data@0.64.2
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
+ full-icu@1.3.1
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.
Problem
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.
Tests so far
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.
So...
Would anyone have an idea about the reason why specifying the path in an environment variable doesn't work, and what I should check?