Skip to content

Commit

Permalink
feat: auto ID's for react-intl components
Browse files Browse the repository at this point in the history
Generates and inserts globally unique id props for react-intl
React components FormattedMessage and FormattedHTMLMessage
  • Loading branch information
bradbarrow committed Feb 8, 2018
1 parent 659bd61 commit 504c729
Show file tree
Hide file tree
Showing 9 changed files with 612 additions and 15 deletions.
11 changes: 11 additions & 0 deletions .all-contributorsrc
Expand Up @@ -68,6 +68,17 @@
"example",
"doc"
]
},
{
"login": "bradbarrow",
"name": "bradbarrow",
"avatar_url": "https://avatars3.githubusercontent.com/u/1264276?v=4",
"profile": "http://bradbarrow.com",
"contributions": [
"code",
"doc",
"test"
]
}
]
}
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -52,7 +52,8 @@
"lib"
],
"dependencies": {
"babel-types": "^6.26.0"
"babel-types": "^6.26.0",
"murmurhash3js": "^3.0.1"
},
"devDependencies": {
"all-contributors-cli": "^4.10.1",
Expand Down
32 changes: 24 additions & 8 deletions readme.md
Expand Up @@ -5,7 +5,7 @@
[![Coverage Status](https://coveralls.io/repos/github/akameco/babel-plugin-react-intl-auto/badge.svg?branch=master)](https://coveralls.io/github/akameco/babel-plugin-react-intl-auto?branch=master)
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest)
[![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors)

> i18n for the component age. Auto management react-intl ID.
Expand All @@ -22,10 +22,10 @@ You can generate json automatically.

Goodbye, global ID!!

### Before
#### Before

```js
import { defineMessages } from 'react-intl'
import { defineMessages, FormattedMessage } from 'react-intl'

export default defineMessages({
hello: {
Expand All @@ -37,9 +37,16 @@ export default defineMessages({
defaultMessage: 'Welcome!',
},
})

const MyComponent = () => (
<FormattedMessage
id="App.Components.Greeting.goodbye"
defaultMessage="goodbye {name}"
/>
)
```

### After
#### After

With babel-plugin-react-intl-auto.

Expand All @@ -50,11 +57,15 @@ export default defineMessages({
hello: 'hello {name}',
welcome: 'Welcome!',
})

const MyComponent = () => <FormattedMessage defaultMessage="goodbye {name}" />
```

See [examples](https://github.com/akameco/babel-plugin-react-intl-auto/tree/master/examples).

with [extract-react-intl-messages](https://github.com/akameco/extract-react-intl-messages).
### With `extract-react-intl-messages`

Example usage with [extract-react-intl-messages](https://github.com/akameco/extract-react-intl-messages).

```
$ extract-messages -l=en -o translations 'src/**/*.js'
Expand All @@ -66,6 +77,7 @@ en.json
{
"components.App.hello": "hello {name}",
"components.App.welcome": "Welcome"
"components.App.189751785": "goodbye {name}" // unique hash of defaultMessage
}
```

Expand Down Expand Up @@ -170,6 +182,8 @@ Default: `false`

if `includeExportName` is `true`, adds named exports as part of the id.

Only works with `defineMessages`.

##### Example

```js
Expand All @@ -192,7 +206,9 @@ exports.

#### extractComments

Use leading comments as the message description
Use leading comments as the message description.

Only works with `defineMessages`

Type: `boolean` <br>
Default: `true`
Expand Down Expand Up @@ -254,8 +270,8 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->

<!-- prettier-ignore -->
| [<img src="https://avatars2.githubusercontent.com/u/4002137?v=4" width="100px;"/><br /><sub><b>akameco</b></sub>](http://akameco.github.io)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=akameco "Code") [⚠️](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=akameco "Tests") [👀](#review-akameco "Reviewed Pull Requests") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=akameco "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/112334?v=4" width="100px;"/><br /><sub><b>Aleksander Heintz</b></sub>](http://alxandr.me)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Alxandr "Code") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Alxandr "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/753919?v=4" width="100px;"/><br /><sub><b>Ryan Leckey</b></sub>](https://github.com/mehcode)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=mehcode "Code") | [<img src="https://avatars1.githubusercontent.com/u/2652619?v=4" width="100px;"/><br /><sub><b>Adam</b></sub>](https://github.com/adam-26)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=adam-26 "Code") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=adam-26 "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/1280915?v=4" width="100px;"/><br /><sub><b>Guylian Cox</b></sub>](https://ephys.github.io)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Ephys "Code") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Ephys "Documentation") [⚠️](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Ephys "Tests") | [<img src="https://avatars1.githubusercontent.com/u/928407?v=4" width="100px;"/><br /><sub><b>Carl Grundberg</b></sub>](http://carlgrundberg.github.io/)<br />[💡](#example-carlgrundberg "Examples") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=carlgrundberg "Documentation") |
| :---: | :---: | :---: | :---: | :---: | :---: |
| [<img src="https://avatars2.githubusercontent.com/u/4002137?v=4" width="100px;"/><br /><sub><b>akameco</b></sub>](http://akameco.github.io)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=akameco "Code") [⚠️](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=akameco "Tests") [👀](#review-akameco "Reviewed Pull Requests") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=akameco "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/112334?v=4" width="100px;"/><br /><sub><b>Aleksander Heintz</b></sub>](http://alxandr.me)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Alxandr "Code") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Alxandr "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/753919?v=4" width="100px;"/><br /><sub><b>Ryan Leckey</b></sub>](https://github.com/mehcode)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=mehcode "Code") | [<img src="https://avatars1.githubusercontent.com/u/2652619?v=4" width="100px;"/><br /><sub><b>Adam</b></sub>](https://github.com/adam-26)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=adam-26 "Code") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=adam-26 "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/1280915?v=4" width="100px;"/><br /><sub><b>Guylian Cox</b></sub>](https://ephys.github.io)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Ephys "Code") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Ephys "Documentation") [⚠️](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=Ephys "Tests") | [<img src="https://avatars1.githubusercontent.com/u/928407?v=4" width="100px;"/><br /><sub><b>Carl Grundberg</b></sub>](http://carlgrundberg.github.io/)<br />[💡](#example-carlgrundberg "Examples") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=carlgrundberg "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/1264276?v=4" width="100px;"/><br /><sub><b>bradbarrow</b></sub>](http://bradbarrow.com)<br />[💻](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=bradbarrow "Code") [📖](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=bradbarrow "Documentation") [⚠️](https://github.com/akameco/babel-plugin-react-intl-auto/commits?author=bradbarrow "Tests") |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |

<!-- ALL-CONTRIBUTORS-LIST:END -->

Expand Down
255 changes: 255 additions & 0 deletions src/__tests__/__snapshots__/components.test.js.snap
@@ -0,0 +1,255 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`default default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;

exports[`default does nothing if component props are spread: does nothing if component props are spread 1`] = `
"
import { FormattedMessage } from 'react-intl'
const props = { defaultMessage: 'hello' };
console.log(<FormattedMessage {...props} />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
const props = { defaultMessage: 'hello' };
console.log(<FormattedMessage {...props} />);
"
`;

exports[`default does nothing if components not imported from react-intl: does nothing if components not imported from react-intl 1`] = `
"
import any from 'any-module'
console.log(<FormattedMessage defaultMessage={getMsg()} />);
↓ ↓ ↓ ↓ ↓ ↓
import any from 'any-module';
console.log(<FormattedMessage defaultMessage={getMsg()} />);
"
`;

exports[`default multiple uses: multiple uses 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
console.log(<FormattedMessage defaultMessage=\\"another\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
console.log(<FormattedMessage id=\\"src.__fixtures__.1418522856\\" defaultMessage=\\"another\\" />);
"
`;

exports[`default with FormattedMessage imported as something else: with FormattedMessage imported as something else 1`] = `
"
import { FormattedMessage as T } from 'react-intl'
console.log(<T defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage as T } from 'react-intl';
console.log(<T id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;

exports[`default with FormattedMessage nested in other JSX: with FormattedMessage nested in other JSX 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(
<div>
<FormattedMessage defaultMessage=\\"hello\\" />
</div>
);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<div>
<FormattedMessage id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />
</div>);
"
`;

exports[`default with a value interpolated in the message: with a value interpolated in the message 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage={\`hello world 2\`} />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.3540954520\\" defaultMessage={\`hello world 2\`} />);
"
`;
exports[`default with a variable as the defaultMessage: with a variable as the defaultMessage 1`] = `
"
import { FormattedMessage } from 'react-intl'
const message = \\"variable message\\";
console.log(<FormattedMessage defaultMessage={message} />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
const message = \\"variable message\\";
console.log(<FormattedMessage id=\\"src.__fixtures__.3082794952\\" defaultMessage={message} />);
"
`;
exports[`extractComments = false default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`filebase = true default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.messages.613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`includeExportName = all default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`includeExportName = true default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`removePrefix = "src" default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`removePrefix = "src/" -- with slash default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`removePrefix = false default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"src.__fixtures__.613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`removePrefix = true, includeExportName = all default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"613153351\\" defaultMessage=\\"hello\\" />);
"
`;
exports[`removePrefix = true, includeExportName = true default: default 1`] = `
"
import { FormattedMessage } from 'react-intl'
console.log(<FormattedMessage defaultMessage=\\"hello\\" />);
↓ ↓ ↓ ↓ ↓ ↓
import { FormattedMessage } from 'react-intl';
console.log(<FormattedMessage id=\\"613153351\\" defaultMessage=\\"hello\\" />);
"
`;
4 changes: 2 additions & 2 deletions src/__tests__/__snapshots__/index.test.js.snap
Expand Up @@ -314,7 +314,7 @@ exports[`default with include value: with include value 1`] = `
import { defineMessages } from 'react-intl'
defineMessages({
hello: \`hello world \${1}\`,
hello: \`hello world \${1+1}\`,
})
↓ ↓ ↓ ↓ ↓ ↓
Expand All @@ -324,7 +324,7 @@ import { defineMessages } from 'react-intl';
defineMessages({
hello: {
'id': 'src.__fixtures__.hello',
'defaultMessage': \`hello world \${1}\`
'defaultMessage': \`hello world \${1 + 1}\`
}
});
"
Expand Down

0 comments on commit 504c729

Please sign in to comment.