Skip to content

Commit

Permalink
Merge pull request #80 from lingui/noop
Browse files Browse the repository at this point in the history
Add i18nMark function for marking strings for extraction
  • Loading branch information
tricoder42 authored Sep 5, 2017
2 parents 69b5d61 + 6c1b683 commit 5800360
Show file tree
Hide file tree
Showing 40 changed files with 412 additions and 114 deletions.
29 changes: 29 additions & 0 deletions docs/ref/react.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
- Providers
- [I18nProvider](#i18nprovider)
- [withI18n](#withi18n)
- Helpers
- [i18nMark](#i18nMark)

|| Example MessageFormat
--- | --
Expand Down Expand Up @@ -392,3 +394,30 @@ const LogoutIcon = withI18n()(

Previous version of this component, named `WithI18n` (upper-cased first letter),
is deprecated and will be removed in [email protected]

### i18nMark

`i18nMark(source: string)`

Mark text for translation, but don't translate it immediatelly. In development, the `i18nMark` function is identity, returning the source string. Such string is extracted to message catalog, so it can be referred in `<Trans>` dynamically:

```jsx
const message = i18nMark('Source string')

<Trans id={message} />
// is the same as
<Trans id="Source string" />
```

This is useful for defining translations outside components:

```jsx
const languages = {
en: i18nMark('English'),
fr: i18nMark('French')
}

Object.keys(languages).map(language =>
<Trans key={language} id={languages[language]} />
)
```
17 changes: 17 additions & 0 deletions packages/babel-plugin-lingui-extract-messages/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

<a name="1.1.0"></a>
# [1.1.0](https://github.com/lingui/js-lingui/compare/babel-plugin-lingui-extract-messages@[email protected]) (2017-09-05)


### Bug Fixes

* Don't raise warnings about translations from variables ([05596ff](https://github.com/lingui/js-lingui/commit/05596ff))
* Use Array.includes instead of polyfill ([0aa585c](https://github.com/lingui/js-lingui/commit/0aa585c))


### Features

* Extract message from i18n_mark identity ([93af236](https://github.com/lingui/js-lingui/commit/93af236))




<a name="1.0.6"></a>
## [1.0.6](https://github.com/lingui/js-lingui/compare/babel-plugin-lingui-extract-messages@[email protected]) (2017-08-28)

Expand Down
6 changes: 3 additions & 3 deletions packages/babel-plugin-lingui-extract-messages/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-plugin-lingui-extract-messages",
"version": "1.0.6",
"version": "1.1.0",
"description": "Extract messages for translation",
"main": "dist/index.js",
"author": {
Expand Down Expand Up @@ -32,8 +32,8 @@
"lingui-conf": "^0.8.1"
},
"devDependencies": {
"babel-plugin-lingui-transform-js": "^1.0.2",
"babel-plugin-lingui-transform-react": "^1.0.5"
"babel-plugin-lingui-transform-js": "^1.0.3",
"babel-plugin-lingui-transform-react": "^1.0.6"
},
"scripts": {
"prepublish": "../../scripts/prepublish.sh"
Expand Down
61 changes: 50 additions & 11 deletions packages/babel-plugin-lingui-extract-messages/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default function ({ types: t }) {
})
}

const isNoopMethod = node => t.isIdentifier(node, { name: 'i18nMark' })
const isI18nMethod = node =>
t.isMemberExpression(node) &&
t.isIdentifier(node.object, { name: 'i18n' }) &&
Expand All @@ -60,14 +61,25 @@ export default function ({ types: t }) {
ImportDeclaration (path) {
const { node } = path

if (node.source.value !== 'lingui-react') return
if (!Array.includes(['lingui-react', 'lingui-i18n'], node.source.value)) return

const importDeclarations = {}
node.specifiers.forEach(specifier => {
importDeclarations[specifier.imported.name] = specifier.local.name
})
if (node.source.value === 'lingui-react') {
node.specifiers.forEach(specifier => {
importDeclarations[specifier.imported.name] = specifier.local.name
})

localTransComponentName = importDeclarations['Trans']
localTransComponentName = importDeclarations['Trans']
}

// Remove imports of i18nMark identity
node.specifiers = node.specifiers.filter(specifier =>
specifier.imported.name !== 'i18nMark'
)

if (!node.specifiers.length) {
path.remove()
}
},

// Extract translation from <Trans /> component.
Expand All @@ -84,8 +96,12 @@ export default function ({ types: t }) {
}, {})

if (!props.id) {
console.warn('Missing message ID, skipping.')
console.warn(generate(node).code)
// <Trans id={message} /> is valid, don't raise warning
const idProp = attrs.filter(item => item.name.name === 'id')[0]
if (idProp === undefined || t.isLiteral(props.id)) {
console.warn('Missing message ID, skipping.')
console.warn(generate(node).code)
}
return
}

Expand All @@ -97,17 +113,35 @@ export default function ({ types: t }) {
const { node } = path
const visited = file.get(VISITED)

if (!isI18nMethod(node.callee) || visited.has(node.callee)) return
if (
// we already visited this node
visited.has(node.callee) ||
// nothing to extract
(!isI18nMethod(node.callee) && !isNoopMethod(node.callee))
) {
return
}

visited.add(node.callee)

if (isNoopMethod(node.callee) && !t.isStringLiteral(node.arguments[0])) {
console.warn('Only string literals are allowed in i18nMark.')
return
}

const attrs = node.arguments[1] && node.arguments[1].properties
? node.arguments[1].properties
: []

const id = node.arguments[0] && node.arguments[0].value
const idArg = node.arguments[0]
const id = idArg && idArg.value
if (!id) {
console.warn('Missing message ID, skipping.')
console.warn(generate(node).code)
// i18n._(message) is valid, don't raise warning
if (idArg === undefined || t.isLiteral(idArg)) {
console.warn('Missing message ID, skipping.')
console.warn(generate(node).code)
}

return
}

Expand All @@ -118,6 +152,11 @@ export default function ({ types: t }) {
}, { id })

collectMessage(path, file, props)

if (isNoopMethod(node.callee)) {
const translation = node.arguments[0]
path.replaceWith(t.stringLiteral(translation.value))
}
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,24 @@ Object {
},
}
`;

exports[`babel-plugin-lingui-extract-messages should extract noop strings 1`] = `
Object {
"Czech": Object {
"origin": Array [
Array [
"packages/babel-plugin-lingui-extract-messages/test/fixtures/noop/actual.js",
5,
],
],
},
"English": Object {
"origin": Array [
Array [
"packages/babel-plugin-lingui-extract-messages/test/fixtures/noop/actual.js",
4,
],
],
},
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ i18n._("{count, plural, one {# book} other {# books}}", {
count: count
}
})
i18n._(message)
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ i18n._("{count, plural, one {# book} other {# books}}", {
values: {
count: count
}
})
});
<Trans id={message} />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { i18nMark } from 'lingui-i18n'

const languages = {
en: i18nMark('English'),
cs: i18nMark('Czech')
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const languages = {
en: 'English',
cs: 'Czech'
};
10 changes: 10 additions & 0 deletions packages/babel-plugin-lingui-extract-messages/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ describe('babel-plugin-lingui-extract-messages', function () {
expect(fs.existsSync(path.join(buildDir, 'jsx/without-lingui.json'))).toBeFalsy()
})

testCase('should extract noop strings', (transform) => {
const result = transform('noop/actual.js')()

const expected = fs.readFileSync(path.join(__dirname, 'fixtures/noop/expected.js'))
expect(result.code.trim()).toEqual(expected.toString().trim())

const messages = JSON.parse(fs.readFileSync(path.join(buildDir, 'noop/actual.json')))
expect(messages).toMatchSnapshot()
})

testCase('should extract all messages from JSX files', (transform) => {
// first run should create all required folders and write messages
expect(transform('jsx/all.js')).not.toThrow()
Expand Down
8 changes: 8 additions & 0 deletions packages/babel-plugin-lingui-transform-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

<a name="1.0.3"></a>
## [1.0.3](https://github.com/lingui/js-lingui/compare/babel-plugin-lingui-transform-js@[email protected]) (2017-09-05)




**Note:** Version bump only for package babel-plugin-lingui-transform-js

<a name="1.0.2"></a>
## [1.0.2](https://github.com/lingui/js-lingui/compare/babel-plugin-lingui-transform-js@[email protected]) (2017-08-28)

Expand Down
2 changes: 1 addition & 1 deletion packages/babel-plugin-lingui-transform-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-plugin-lingui-transform-js",
"version": "1.0.2",
"version": "1.0.3",
"description": "Transform lingui-i18n methods to ICU message format",
"main": "dist/index.js",
"author": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ i18n.t`
and replace them with one space.
`;
i18n._(message);
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ i18n._("My name is {name}", {
}
});
i18n._("Remove any newlines... and replace them with one space.");
i18n._(message);
8 changes: 8 additions & 0 deletions packages/babel-plugin-lingui-transform-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

<a name="1.0.6"></a>
## [1.0.6](https://github.com/lingui/js-lingui/compare/babel-plugin-lingui-transform-react@[email protected]) (2017-09-05)




**Note:** Version bump only for package babel-plugin-lingui-transform-react

<a name="1.0.5"></a>
## [1.0.5](https://github.com/lingui/js-lingui/compare/babel-plugin-lingui-transform-react@[email protected]) (2017-08-28)

Expand Down
2 changes: 1 addition & 1 deletion packages/babel-plugin-lingui-transform-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-plugin-lingui-transform-react",
"version": "1.0.5",
"version": "1.0.6",
"description": "Transform React components to ICU message format",
"main": "dist/index.js",
"author": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ import { Trans } from 'lingui-react';
<Trans>Hello World</Trans>;
<Trans id="Hello World">Hello World</Trans>;
<Trans id="msg.hello">Hello World</Trans>;
<Trans id={msg} />;
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ import { Trans } from 'lingui-react';
<Trans id="Hello World" />;
<Trans id="Hello World" />;
<Trans id="msg.hello" defaults="Hello World" />;
<Trans id={msg} />;
8 changes: 8 additions & 0 deletions packages/babel-preset-lingui-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

<a name="1.0.3"></a>
## [1.0.3](https://github.com/lingui/js-lingui/compare/[email protected]@1.0.3) (2017-09-05)




**Note:** Version bump only for package babel-preset-lingui-js

<a name="1.0.2"></a>
## [1.0.2](https://github.com/lingui/js-lingui/compare/[email protected]@1.0.2) (2017-08-28)

Expand Down
4 changes: 2 additions & 2 deletions packages/babel-preset-lingui-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-preset-lingui-js",
"version": "1.0.2",
"version": "1.0.3",
"description": "Lingui preset for Javascript apps",
"main": "index.js",
"author": {
Expand All @@ -20,6 +20,6 @@
"url": "https://github.com/lingui/js-lingui/issues"
},
"dependencies": {
"babel-plugin-lingui-transform-js": "^1.0.2"
"babel-plugin-lingui-transform-js": "^1.0.3"
}
}
8 changes: 8 additions & 0 deletions packages/babel-preset-lingui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

<a name="1.0.5"></a>
## [1.0.5](https://github.com/lingui/js-lingui/compare/[email protected]@1.0.5) (2017-09-05)




**Note:** Version bump only for package babel-preset-lingui-react

<a name="1.0.4"></a>
## [1.0.4](https://github.com/lingui/js-lingui/compare/[email protected]@1.0.4) (2017-08-28)

Expand Down
6 changes: 3 additions & 3 deletions packages/babel-preset-lingui-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-preset-lingui-react",
"version": "1.0.4",
"version": "1.0.5",
"description": "Lingui preset for React apps",
"main": "index.js",
"author": {
Expand All @@ -20,7 +20,7 @@
"url": "https://github.com/lingui/js-lingui/issues"
},
"dependencies": {
"babel-plugin-lingui-transform-js": "^1.0.2",
"babel-plugin-lingui-transform-react": "^1.0.5"
"babel-plugin-lingui-transform-js": "^1.0.3",
"babel-plugin-lingui-transform-react": "^1.0.6"
}
}
Loading

0 comments on commit 5800360

Please sign in to comment.