Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
babel-plugin-precompile-intl
Advanced tools
Compile translations in ICU message format to invocable functions at build time
This babel plugin compiles translations in the ICU message syntax into executable functions at build time, analyzing the used features and importing the required runtime helpers from precompile-intl-runtime to perform the operations that can't be performed at build time.
This approach is different than the taken by libraries like intl-messageformat or format-message, which do all the work in the browser. The approach taken by those libraries is more flexible as you can just load json files with translations in plain text and that's it, but it also means the library needs to ship a parser for the ICU message syntax, and it always has to have ship code for all the features that the ICU syntax supports, even features you might not use, making those libraries several times bigger.
The strategy used by this library assumes that your app will have some sort of built process that you can use to analyze and precompile the messages in your app. This process spares the browser of the burden of doing the same process in the user's devices, resulting in smaller and faster apps.
Ok, let's check it with an example.
Say you have a file with translations like this:
{
"plain": "Some text without interpolations",
"interpolated": "A text where I interpolate {count} times",
"time": "Now is {now, time}",
"time-custom-format": "The hour is {now, time, hour}",
"date": "Today is {today, date}",
"date-custom-format": "Today is {today, date, abbr-full}",
"number": "My favorite number is {n, number}",
"percent": "My favorite number is {n, number, percent}",
"pluralized": "I have {count, plural,=0 {no cats} =1 {one cat} other {{count} cats}}",
"pluralized-with-hash": "I have {count, plural, zero {no cats} one {just # cat} other {# cats}}",
"selected": "{gender, select, male {He is a good boy} female {She is a good girl} other {They are good fellas}}",
}
This babel plugin will precompile that file into something like this:
import { __date, __interpolate, __number, __plural, __select, __time } from "precompile-intl-runtime";
export default {
plain: "Some text without interpolations",
interpolated: `A text where I interpolate ${__interpolate(count)} times`,
time: now => `Now is ${__time(now)}`,
"time-custom-format": now => `The hour is ${__time(now, "hour")}`,
date: today => `Today is ${__date(today)}`,
"date-custom-format": today => `Today is ${__date(today, "abbr-full")}`,
number: n => `My favorite number is ${__number(n)}`,
percent: n => `My favorite number is ${__number(n, "percent")}`,
pluralized: count => `I have ${__plural(count, { 0: "no cats", 1: "one cat", h: `${__interpolate(count)} cats`})}`,
"pluralized-with-hash": count => `I have ${__plural(count, { z: "no cats", o: `just ${count} cat`, h: `${count} cats`})}`,
selected: gender => __select(gender, { male: "He is a good boy", female: "She is a good girl", other: "They are good fellas"})
}
As you see, translations with no logic remain unchanged, but translations that take arguments are transformed into functions that
take those arguments and use some runtime helpers from precompile-intl-runtime
, the runtime counterpart of this library.
Although this output may seem very verbose, it is designed to minify extremely well. Your minification step will transform keys like this:
"pluralized-with-hash": "I have {count, plural, zero {no cats} one {just # cat} other {# cats}}",
--------------------------------------------------------------------------------------------------
"pluralized-with-hash":t=>`I have ${jt(t,{z:"no cats",o:`just ${t} cat`,h:`${t} cats`})}`
On average the minified output is between 5% and 10% smaller than the original input, and the runtime library is much smaller than other alternatives and even smaller because it can be tree-shaken so only the helpers your translations need are included, varying the weight of the library between 1k and just a few bytes.
If you store translations in *.js
file, you may use template literals (strings with backticks). These strings may span multiple lines in the file.
export default {
notice: `
Great to see you again!
... long text ...
`
}
Note: you should not use JavaScript variables and expressions in these template literals. This syntax is not supported:
const name = "Gregory"
export default {
notice: `Hello, ${name}`
}
It will be better to use interpolations and pass values on call:
// Translations file.
export default {
notice: `Hello, {name}`
}
// Page, layout, etc. See `precompile-intl-runtime`.
$t('notice', {values: {name: 'Gregory'}})
FAQs
Compile translations in ICU message format to invocable functions at build time
The npm package babel-plugin-precompile-intl receives a total of 1,388 weekly downloads. As such, babel-plugin-precompile-intl popularity was classified as popular.
We found that babel-plugin-precompile-intl demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.