Bundling with formatjs

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-react-intl

npm i -D babel-plugin-react-intl

Let's take this simple example:

import {FormattedMessage} from 'react-intl';
<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-react-intl similarly as below:

babel.config.json

{
"plugins": [
[
"react-intl",
{
"extractFromFormatMessageCall": true,
"idInterpolationPattern": "[sha512:contenthash:base64:6]"
}
]
]
}

This will produce the following JS

const {FormattedMessage} = require('react-intl');
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 ttypescript, ts-loader or similar.

Let's take this simple example:

import {FormattedMessage} from 'react-intl';
<FormattedMessage
description="A message"
defaultMessage="My name is {name}"
values={{
name: userName,
}}
/>;

ts-loader

You can add this in your webpack config ts-loader.

import {transform} from '@formatjs/ts-transformer';
// webpack config
module.exports = {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
getCustomTransformers() {
return {
before: [
transform({
extractFromFormatMessageCall: true,
overrideIdFn: '[sha512:contenthash:base64:6]',
}),
],
};
},
},
},
],
exclude: /node_modules/,
},
],
};

This will produce the following JS

const {FormattedMessage} = require('react-intl');
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.