Skip to content
This repository was archived by the owner on Jun 8, 2019. It is now read-only.

Commit d0e0171

Browse files
authored
Merge pull request #74 from yahoo/remove-description
Remove description after extracting Message Descriptors
2 parents 1860bff + 8817eea commit d0e0171

File tree

8 files changed

+109
-23
lines changed

8 files changed

+109
-23
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ $ npm install babel-plugin-react-intl
1616

1717
The default message descriptors for the app's default language will be extracted from: `defineMessages()`, `<FormattedMessage>`, and `<FormattedHTMLMessage>`; all of which are named exports of the React Intl package.
1818

19+
If a message descriptor has a `description`, it'll be removed from the source after it's extracted to save bytes since it isn't used at runtime.
20+
1921
### Via `.babelrc` (Recommended)
2022

2123
**.babelrc**

src/index.js

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ const FUNCTION_NAMES = [
2020

2121
const DESCRIPTOR_PROPS = new Set(['id', 'description', 'defaultMessage']);
2222

23-
export default function () {
23+
const EXTRACTED_TAG = Symbol('ReactIntlExtracted');
24+
25+
export default function ({types: t}) {
2426
function getModuleSourceName(opts) {
2527
return opts.moduleSourceName || 'react-intl';
2628
}
@@ -153,6 +155,14 @@ export default function () {
153155
return importedNames.some((name) => path.referencesImport(mod, name));
154156
}
155157

158+
function tagAsExtracted(path) {
159+
path.node[EXTRACTED_TAG] = true;
160+
}
161+
162+
function wasExtracted(path) {
163+
return !!path.node[EXTRACTED_TAG];
164+
}
165+
156166
return {
157167
visitor: {
158168
Program: {
@@ -192,10 +202,13 @@ export default function () {
192202
},
193203

194204
JSXOpeningElement(path, state) {
195-
const {file, opts} = state;
196-
const moduleSourceName = getModuleSourceName(opts);
205+
if (wasExtracted(path)) {
206+
return;
207+
}
197208

198-
let name = path.get('name');
209+
const {file, opts} = state;
210+
const moduleSourceName = getModuleSourceName(opts);
211+
const name = path.get('name');
199212

200213
if (name.referencesImport(moduleSourceName, 'FormattedPlural')) {
201214
file.log.warn(
@@ -231,7 +244,20 @@ export default function () {
231244
descriptor = evaluateMessageDescriptor(descriptor, {
232245
isJSXSource: true,
233246
});
247+
234248
storeMessage(descriptor, path, state);
249+
250+
// Remove description since it's not used at runtime.
251+
attributes.some((attr) => {
252+
let ketPath = attr.get('name');
253+
if (getMessageDescriptorKey(ketPath) === 'description') {
254+
attr.remove();
255+
return true;
256+
}
257+
});
258+
259+
// Tag the AST node so we don't try to extract it twice.
260+
tagAsExtracted(path);
235261
}
236262
}
237263
},
@@ -254,6 +280,10 @@ export default function () {
254280
function processMessageObject(messageObj) {
255281
assertObjectExpression(messageObj);
256282

283+
if (wasExtracted(messageObj)) {
284+
return;
285+
}
286+
257287
let properties = messageObj.get('properties');
258288

259289
let descriptor = createMessageDescriptor(
@@ -266,6 +296,21 @@ export default function () {
266296
// Evaluate the Message Descriptor values, then store it.
267297
descriptor = evaluateMessageDescriptor(descriptor);
268298
storeMessage(descriptor, messageObj, state);
299+
300+
// Remove description since it's not used at runtime.
301+
messageObj.replaceWith(t.objectExpression([
302+
t.objectProperty(
303+
t.stringLiteral('id'),
304+
t.stringLiteral(descriptor.id)
305+
),
306+
t.objectProperty(
307+
t.stringLiteral('defaultMessage'),
308+
t.stringLiteral(descriptor.defaultMessage)
309+
),
310+
]));
311+
312+
// Tag the AST node so we don't try to extract it twice.
313+
tagAsExtracted(messageObj);
269314
}
270315

271316
if (referencesImport(callee, moduleSourceName, FUNCTION_NAMES)) {

test/fixtures/FormattedHTMLMessage/expected.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ var Foo = function (_Component) {
3434
value: function render() {
3535
return _react2.default.createElement(_reactIntl.FormattedHTMLMessage, {
3636
id: 'foo.bar.baz',
37-
defaultMessage: '<h1>Hello World!</h1>',
38-
description: 'The default message.'
37+
defaultMessage: '<h1>Hello World!</h1>'
3938
});
4039
}
4140
}]);

test/fixtures/FormattedMessage/expected.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ var Foo = function (_Component) {
3434
value: function render() {
3535
return _react2.default.createElement(_reactIntl.FormattedMessage, {
3636
id: 'foo.bar.baz',
37-
defaultMessage: 'Hello World!',
38-
description: 'The default message.'
37+
defaultMessage: 'Hello World!'
3938
});
4039
}
4140
}]);

test/fixtures/defineMessages/expected.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
2222

2323
var msgs = (0, _reactIntl.defineMessages)({
2424
header: {
25-
id: 'foo.bar.baz',
26-
defaultMessage: 'Hello World!',
27-
description: 'The default message'
25+
'id': 'foo.bar.baz',
26+
'defaultMessage': 'Hello World!'
2827
},
2928
content: {
30-
id: 'foo.bar.biff',
31-
defaultMessage: 'Hello Nurse!',
32-
description: 'Another message'
29+
'id': 'foo.bar.biff',
30+
'defaultMessage': 'Hello Nurse!'
3331
}
3432
});
3533

test/fixtures/moduleSourceName/expected.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ var Foo = function (_Component) {
5454
null,
5555
_react2.default.createElement(_reactI18n.FormattedMessage, {
5656
id: 'foo.bar.baz',
57-
defaultMessage: 'Hello World!',
58-
description: 'The default message.'
57+
defaultMessage: 'Hello World!'
5958
}),
6059
msgs
6160
);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React, {Component} from 'react';
2+
import {defineMessages, FormattedMessage} from 'react-intl';
3+
4+
const messages = defineMessages({
5+
foo: {
6+
id: 'greeting-user',
7+
description: 'Greeting the user',
8+
defaultMessage: 'Hello, {name}',
9+
},
10+
});
11+
12+
export default class Foo extends Component {
13+
render() {
14+
return (
15+
<FormattedMessage
16+
id='greeting-world'
17+
description='Greeting to the world'
18+
defaultMessage='Hello World!'
19+
/>
20+
);
21+
}
22+
}

test/index.js

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const skipTests = [
1515
'extractSourceLocation',
1616
'moduleSourceName',
1717
'icuSyntax',
18+
'removeDescriptions',
1819
];
1920

2021
const fixturesDir = path.join(__dirname, 'fixtures');
@@ -74,6 +75,22 @@ describe('options', () => {
7475
}
7576
});
7677

78+
it('removes descriptions when plugin is applied more than once', () => {
79+
const fixtureDir = path.join(fixturesDir, 'removeDescriptions');
80+
81+
try {
82+
transform(path.join(fixtureDir, 'actual.js'), {
83+
enforceDescriptions: true,
84+
}, {
85+
multiplePasses: true,
86+
});
87+
assert(true);
88+
} catch (e) {
89+
console.error(e);
90+
assert(false);
91+
}
92+
});
93+
7794
it('respects moduleSourceName', () => {
7895
const fixtureDir = path.join(fixturesDir, 'moduleSourceName');
7996

@@ -133,13 +150,18 @@ const BASE_OPTIONS = {
133150
messagesDir: baseDir,
134151
};
135152

136-
function transform(filePath, options = {}) {
153+
function transform(filePath, options = {}, {multiplePasses = false} = {}) {
154+
function getPluginConfig() {
155+
return [plugin, {
156+
...BASE_OPTIONS,
157+
...options,
158+
}];
159+
}
160+
137161
return babel.transformFileSync(filePath, {
138-
plugins: [
139-
[plugin, {
140-
...BASE_OPTIONS,
141-
...options,
142-
}],
143-
],
162+
plugins: multiplePasses ? [
163+
getPluginConfig(),
164+
getPluginConfig(),
165+
] : [getPluginConfig()],
144166
}).code;
145167
}

0 commit comments

Comments
 (0)