If I run this code in the browser and node I obtain two different results:
const moneyFormatter = new Intl.NumberFormat('it-IT', {
style: 'currency',
currency: 'EUR',
minimumFractionDigits: 2
});
moneyFormatter.format(1);
Browser: 1,00 €
Node: €1.00
ICU and Node
This problem is caused by the missing ICU data in the default Node build.
Nodejs docs explain it this feature well:
Node.js (and its underlying V8 engine) uses ICU to implement these features in native C/C++ code. However, some of them require a very large ICU data file in order to support all locales of the world.
And its limitations in the default node build:
Because it is expected that most Node.js users will make use of only a small portion of ICU functionality, only a subset of the full ICU data set is provided by Node.js by default.
So:
Several options are provided for customizing and expanding the ICU data set either when building or running Node.js.
Quick solution
Install the full-icu
npm package and you're done: every locale will be installed and can be used. Just start you app with a dedicated env var pointing to the icu dataset installation:
NODE_ICU_DATA=node_modules/full-icu node YOURAPP.js
Or, using the alternative node option:
node --icu-data-dir=node_modules/full-icu YOURAPP.js
The only disadvantage of this solution is the space required for the full icu dataset: ~27Mb.
Slow, but space optimized solution
Compile node from source bundling it with only a specific ICU.
Checking available locales
Intl.NumberFormat.supportedLocalesOf('it')
It returns an empty array []
if the locale is not supported.
It returns an array with the locale id ['it']
if the locale is supported.