Now that you've had a working pipeline. It's time to dive deeper on how to optimize the build with formatjs. From Message Extraction guide, we explicitly recommend against explicit ID due to potential collision in large application. While our extractor can insert IDs in the extracted JSON file, you'd need to also insert those IDs into the compiled JS output. This guide will cover how to do that.
Using babel-plugin-formatjs#
npm i -D babel-plugin-formatjs
Let's take this simple example:
<FormattedMessage
description="A message"
defaultMessage="My name is {name}"
values={{
name: userName,
}}
/>
During runtime this will throw an Error saying ID is required. In order to inject an ID in the transpiled JS, you can use our babel-plugin-formatjs similarly as below:
babel.config.json
{
"plugins": [
[
"formatjs",
{
"idInterpolationPattern": "[sha512:contenthash:base64:6]",
"ast": true
}
]
]
}
This will produce the following JS
React.createElement(FormattedMessage, {
id: '179jda',
defaultMessage: 'My name is {name}',
values: {
name: userName,
},
})
description
Our plugin also removes description because it's only for translator, not end-user.
Using @formatjs/ts-transformer#
npm i -D @formatjs/ts-transformer
If you're using TypeScript, in order to enable custom AST transformer you should consider using ts-patch, ts-loader or similar.
Let's take this simple example:
<FormattedMessage
description="A message"
defaultMessage="My name is {name}"
values={{
name: userName,
}}
/>
ts-loader#
You can add this in your webpack config ts-loader.
// webpack config
module.exports = {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
getCustomTransformers() {
return {
before: [
transform({
overrideIdFn: '[sha512:contenthash:base64:6]',
}),
],
}
},
},
},
],
exclude: /node_modules/,
},
],
}
This will produce the following JS
React.createElement(FormattedMessage, {
id: '179jda',
defaultMessage: 'My name is {name}',
values: {
name: userName,
},
})
description
Our transformer also removes description because it's only for translator, not end-user.
Vite#
If you use vite, you will need to use babel instead of esbuild. You can learn why in #3225, with an example vite.config.ts to get started.