i18n for the component age. Auto management react-intl ID
npm install babel-plugin-react-intl-auto





> i18n for the component age. Auto management react-intl ID.
React Intl is awesome. But, Global ID management is difficult and confusing.
Many projects, like react-boilerplate, give the ID to the name of the component as a prefix.
But it is redundant and troublesome.
This babel-plugin releases you from cumbersome ID management.
Based on the file path, this automatically generates a prefixed id.
Also, we strongly encourage you to use extract-react-intl-messages.
You can generate json automatically.
Goodbye, global ID!!
#### Before
``js
import { defineMessages, FormattedMessage } from 'react-intl'
export default defineMessages({
hello: {
id: 'App.Components.Greeting.hello',
defaultMessage: 'hello {name}',
},
welcome: {
id: 'App.Components.Greeting.welcome',
defaultMessage: 'Welcome!',
},
})
const MyComponent = () => (
defaultMessage="goodbye {name}"
/>
)
`
#### After
With babel-plugin-react-intl-auto.
`js
import { defineMessages, FormattedMessage } from 'react-intl'
export default defineMessages({
hello: 'hello {name}',
welcome: 'Welcome!',
})
const MyComponent = () =>
`
See examples.
Example usage with extract-react-intl-messages.
``
$ extract-messages -l=en -o translations 'src/*/.js'
en.json
`json`
{
"components.App.hello": "hello {name}",
"components.App.welcome": "Welcome",
"components.App.189751785": "goodbye {name}" // unique hash of defaultMessage
}
npm
`shell
$ npm install --save-dev babel-plugin-react-intl-auto
yarn
`shell
$ yarn add --dev babel-plugin-react-intl-autoOptional: TypeScript support
$ yarn add --dev @babel/plugin-transform-typescript
`Usage
.babelrc
`json
{
"plugins": [
[
"react-intl-auto",
{
"removePrefix": "app/",
"filebase": false
}
]
]
}
`$3
Input:
`js
import { injectIntl } from 'react-intl'const MyComponent = ({ intl }) => {
const label = intl.formatMessage({ defaultMessage: 'Submit button' })
return
}
injectIntl(MyComponent)
`↓ ↓ ↓
Output:
`js
import { injectIntl } from 'react-intl'const MyComponent = ({ intl }) => {
const label = intl.formatMessage({
id: 'App.Components.Button.label',
defaultMessage: 'Submit button',
})
return
}
injectIntl(MyComponent)
`$3
Input:
`js
import { useIntl } from 'react-intl'const MyComponent = () => {
const intl = useIntl()
const label = intl.formatMessage({ defaultMessage: 'Submit button' })
return
}
`↓ ↓ ↓
Output:
`js
import { useIntl } from 'react-intl'const MyComponent = () => {
const intl = useIntl()
const label = intl.formatMessage({
id: 'App.Components.Button.label',
defaultMessage: 'Submit button',
})
return
}
`$3
#### removePrefix
remove prefix.
Type:
string | boolean
Default: ''if
removePrefix is true, no file path prefix is included in the id.##### Example (src/components/App/messages.js)
when
removePrefix is "src"`js
import { defineMessages } from 'react-intl';export default defineMessages({
hello: 'hello world'
});
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
hello: {
id: 'components.App.hello',
defaultMessage: 'hello world'
}
});
`when
removePrefix is "src.components"`js
import { defineMessages } from 'react-intl';export default defineMessages({
hello: 'hello world'
});
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
hello: {
id: 'App.hello',
defaultMessage: 'hello world'
}
});
`when
removePrefix is true`js
import { defineMessages } from 'react-intl';export default defineMessages({
hello: 'hello world'
});
↓ ↓ ↓ ↓ ↓ ↓
import { defineMessages } from 'react-intl';
export default defineMessages({
hello: {
id: 'hello',
defaultMessage: 'hello world'
}
});
`#### filebase
Type:
boolean
Default: falseif
filebase is true, generate id with filename.#### moduleSourceName
Type:
string
Default: react-intlif set, enables to use custom module as a source for _defineMessages_ etc.
https://github.com/akameco/babel-plugin-react-intl-auto/issues/74#issuecomment-528562743
#### includeExportName
Type:
boolean | 'all'
Default: falseif
includeExportName is true, adds named exports as part of the id.Only works with
defineMessages.##### Example
`js
export const test = defineMessages({
hello: 'hello {name}',
}) ↓ ↓ ↓ ↓ ↓ ↓
export const test = defineMessages({
hello: {
id: 'path.to.file.test.hello',
defaultMessage: 'hello {name}',
},
})
`If includeExportName is
'all', it will also add default to the id on default
exports.#### extractComments
Use leading comments as the message description.
Only works with
defineMessagesType:
boolean
Default: true##### Example
`js
export const test = defineMessages({
// Message used to greet the user
hello: 'hello {name}',
}) ↓ ↓ ↓ ↓ ↓ ↓
export const test = defineMessages({
hello: {
id: 'path.to.file.test.hello',
defaultMessage: 'hello {name}',
description: 'Message used to greet the user',
},
})
`#### useKey
Only works with
intl.formatMessage, FormattedMessage and FormattedHTMLMessage. Instead of
generating an ID by hashing defaultMessage, it will use the key property if
it exists.Type:
boolean
Default: false##### Example
`js
intl.formatMessage({
key: 'foobar',
defaultMessage: 'hello'
}); ↓ ↓ ↓ ↓ ↓ ↓
intl.formatMessage({
key: 'foobar',
defaultMessage: 'hello',
"id": "path.to.file.foobar"
});
``js
↓ ↓ ↓ ↓ ↓ ↓
`#### separator
Allows you to specify a custom separator
Type:
string
Default: .##### Example
when
separator is "_"`js
export const test = defineMessages({
hello: 'hello {name}',
}) ↓ ↓ ↓ ↓ ↓ ↓
export const test = defineMessages({
hello: {
id: 'path_to_file_test_hello',
defaultMessage: 'hello {name}',
},
})
`#### relativeTo
Allows you to specify the directory that is used when determining a file's prefix.
This option is useful for monorepo setups.
Type:
string
Default: process.cwd()##### Example
Folder structure with two sibling packages.
packageB contains babel config and depends on packageA.`bash
|- packageA
| |
| -- componentA
|
|- packageB
| |
| -- componentB
| |
| -- .babelrc
`Set
relativeTo to parent directory in packageB babel config`js
{
"plugins": [
[
"react-intl-auto",
{
"relativeTo": "..",
// ...
},
],
]
}
`Run babel in packageB
`bash
cd packageB && babel
`Messages in
componentA are prefixed relative to the project root`js
export const test = defineMessages({
hello: 'hello {name}',
}) ↓ ↓ ↓ ↓ ↓ ↓
export const test = defineMessages({
hello: {
id: 'packageA.componentA.hello',
defaultMessage: 'hello {name}',
},
})
`$3
##### Example
`js
const messages = { hello: 'hello world' }export default defineMessages(messages)
↓ ↓ ↓ ↓ ↓ ↓
const messages = {
hello: {
id: 'path.to.file.hello',
defaultMessage: 'hello wolrd'
}
};
export default defineMessages(messages);
`TypeScript
TypeScript support is bundled with this package. Be sure to include our type
definition and run
@babel/plugin-transform-typescript beforehand. This way,
you can also be empowered by extract-react-intl-messages.$3
`json
{
"compilerOptions": {
// ...
"jsx": "preserve"
// ...
},
"include": ["node_modules/babel-plugin-react-intl-auto/*/.d.ts"]
}
`$3
`json
{
"plugins": [["@babel/plugin-transform-typescript"], ["react-intl-auto"]]
}
`$3
Use
babel-loader along with ts-loader when using webpack as well.`js
module.exports = {
module: {
rules: [
{
test: /\.tsx?$/,
exclude: [/node_modules/],
use: [
{
loader: 'babel-loader',
},
{
loader: 'ts-loader',
},
],
},
],
},
}
``If you want short consistent hash values for the ID, you can use react-intl-id-hash in addition to this plugin to help reduce your applications bundle size.
Extract react-intl messages.
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
MIT © akameco