Skip to content
This repository was archived by the owner on May 4, 2020. It is now read-only.

Commit f7ce912

Browse files
author
Long Ho
committed
feat(babel-plugin-react-intl): support extracting single message from defineMessage macro
1 parent c301ca0 commit f7ce912

File tree

3 files changed

+189
-4
lines changed

3 files changed

+189
-4
lines changed

packages/babel-plugin-react-intl/src/index.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -635,13 +635,13 @@ export default declare((api: any, options: OptionsSchema) => {
635635
// Check that this is `defineMessages` call
636636
if (
637637
isMultipleMessagesDeclMacro(callee, moduleSourceName) ||
638-
isSingularMessagesDeclMacro(callee)
638+
isSingularMessagesDeclMacro(callee, moduleSourceName)
639639
) {
640640
const firstArgument = path.get('arguments')[0];
641641
const messagesObj = getMessagesObjectFromExpression(firstArgument);
642642

643643
if (assertObjectExpression(messagesObj, callee)) {
644-
if (isSingularMessagesDeclMacro(callee)) {
644+
if (isSingularMessagesDeclMacro(callee, moduleSourceName)) {
645645
processMessageObject(messagesObj as NodePath<ObjectExpression>);
646646
} else {
647647
messagesObj
@@ -674,8 +674,14 @@ function isMultipleMessagesDeclMacro(
674674
);
675675
}
676676

677-
function isSingularMessagesDeclMacro(callee: NodePath) {
678-
return referencesImport(callee, '@formatjs/macro', ['_']);
677+
function isSingularMessagesDeclMacro(
678+
callee: NodePath,
679+
moduleSourceName: string
680+
) {
681+
return (
682+
referencesImport(callee, moduleSourceName, ['defineMessage']) ||
683+
referencesImport(callee, '@formatjs/macro', ['_'])
684+
);
679685
}
680686

681687
function getMessagesObjectFromExpression(

packages/babel-plugin-react-intl/test/__snapshots__/index.test.ts.snap

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,136 @@ Array [
5555
]
5656
`;
5757

58+
exports[`emit asserts for: output match: defineMessage 1`] = `
59+
Object {
60+
"messages": Array [
61+
Object {
62+
"defaultMessage": "Hello World!",
63+
"description": "The default message",
64+
"id": "foo.bar.baz",
65+
},
66+
Object {
67+
"defaultMessage": "Hello Nurse!",
68+
"description": "Another message",
69+
"id": "foo.bar.biff",
70+
},
71+
Object {
72+
"defaultMessage": "{count, plural, =0 {😭} one {# kitten} other {# kittens}}",
73+
"description": "Counts kittens",
74+
"id": "app.home.kittens",
75+
},
76+
Object {
77+
"defaultMessage": " Some whitespace ",
78+
"description": "Whitespace",
79+
"id": "trailing.ws",
80+
},
81+
Object {
82+
"defaultMessage": "A quoted value ''{value}'",
83+
"description": "Escaped apostrophe",
84+
"id": "escaped.apostrophe",
85+
},
86+
],
87+
"meta": Object {
88+
"project": "amazing",
89+
},
90+
}
91+
`;
92+
93+
exports[`emit asserts for: output match: defineMessage 2`] = `
94+
"\\"use strict\\";
95+
96+
Object.defineProperty(exports, \\"__esModule\\", {
97+
value: true
98+
});
99+
exports.default = void 0;
100+
101+
var _react = _interopRequireWildcard(require(\\"react\\"));
102+
103+
var _reactIntl = require(\\"react-intl\\");
104+
105+
function _getRequireWildcardCache() { if (typeof WeakMap !== \\"function\\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
106+
107+
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== \\"object\\" && typeof obj !== \\"function\\") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
108+
109+
// @react-intl project:amazing
110+
const msgs = {
111+
header: (0, _reactIntl.defineMessage)({
112+
\\"id\\": \\"foo.bar.baz\\",
113+
\\"defaultMessage\\": \\"Hello World!\\"
114+
}),
115+
content: (0, _reactIntl.defineMessage)({
116+
\\"id\\": \\"foo.bar.biff\\",
117+
\\"defaultMessage\\": \\"Hello Nurse!\\"
118+
}),
119+
kittens: (0, _reactIntl.defineMessage)({
120+
\\"id\\": \\"app.home.kittens\\",
121+
\\"defaultMessage\\": \\"{count, plural, =0 {\\\\uD83D\\\\uDE2D} one {# kitten} other {# kittens}}\\"
122+
}),
123+
trailingWhitespace: (0, _reactIntl.defineMessage)({
124+
\\"id\\": \\"trailing.ws\\",
125+
\\"defaultMessage\\": \\" Some whitespace \\"
126+
}),
127+
escaped: (0, _reactIntl.defineMessage)({
128+
\\"id\\": \\"escaped.apostrophe\\",
129+
\\"defaultMessage\\": \\"A quoted value ''{value}'\\"
130+
})
131+
};
132+
133+
class Foo extends _react.Component {
134+
render() {
135+
return (
136+
/*#__PURE__*/
137+
_react.default.createElement(\\"div\\", null,
138+
/*#__PURE__*/
139+
_react.default.createElement(\\"h1\\", null,
140+
/*#__PURE__*/
141+
_react.default.createElement(_reactIntl.FormattedMessage, msgs.header)),
142+
/*#__PURE__*/
143+
_react.default.createElement(\\"p\\", null,
144+
/*#__PURE__*/
145+
_react.default.createElement(_reactIntl.FormattedMessage, msgs.content)),
146+
/*#__PURE__*/
147+
_react.default.createElement(\\"p\\", null,
148+
/*#__PURE__*/
149+
_react.default.createElement(_reactIntl.FormattedMessage, msgs.kittens)))
150+
);
151+
}
152+
153+
}
154+
155+
exports.default = Foo;"
156+
`;
157+
158+
exports[`emit asserts for: output match: defineMessage 3`] = `
159+
Array [
160+
Object {
161+
"defaultMessage": "Hello World!",
162+
"description": "The default message",
163+
"id": "foo.bar.baz",
164+
},
165+
Object {
166+
"defaultMessage": "Hello Nurse!",
167+
"description": "Another message",
168+
"id": "foo.bar.biff",
169+
},
170+
Object {
171+
"defaultMessage": "{count, plural, =0 {😭} one {# kitten} other {# kittens}}",
172+
"description": "Counts kittens",
173+
"id": "app.home.kittens",
174+
},
175+
Object {
176+
"defaultMessage": " Some whitespace ",
177+
"description": "Whitespace",
178+
"id": "trailing.ws",
179+
},
180+
Object {
181+
"defaultMessage": "A quoted value ''{value}'",
182+
"description": "Escaped apostrophe",
183+
"id": "escaped.apostrophe",
184+
},
185+
]
186+
`;
187+
58188
exports[`emit asserts for: output match: defineMessages 1`] = `
59189
Object {
60190
"messages": Array [
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// @react-intl project:amazing
2+
import React, {Component} from 'react';
3+
import {defineMessage, FormattedMessage} from 'react-intl';
4+
5+
const msgs = {
6+
header: defineMessage({
7+
id: 'foo.bar.baz',
8+
defaultMessage: 'Hello World!',
9+
description: 'The default message',
10+
}),
11+
content: defineMessage({
12+
id: 'foo.bar.biff',
13+
defaultMessage: 'Hello Nurse!',
14+
description: 'Another message',
15+
}),
16+
kittens: defineMessage({
17+
id: 'app.home.kittens',
18+
description: 'Counts kittens',
19+
defaultMessage: '{count, plural, =0 {😭} one {# kitten} other {# kittens}}',
20+
}),
21+
trailingWhitespace: defineMessage({
22+
id: 'trailing.ws',
23+
description: 'Whitespace',
24+
defaultMessage: ' Some whitespace ',
25+
}),
26+
escaped: defineMessage({
27+
id: 'escaped.apostrophe',
28+
description: 'Escaped apostrophe',
29+
defaultMessage: "A quoted value ''{value}'",
30+
}),
31+
};
32+
33+
export default class Foo extends Component {
34+
render() {
35+
return (
36+
<div>
37+
<h1>
38+
<FormattedMessage {...msgs.header} />
39+
</h1>
40+
<p>
41+
<FormattedMessage {...msgs.content} />
42+
</p>
43+
<p>
44+
<FormattedMessage {...msgs.kittens} />
45+
</p>
46+
</div>
47+
);
48+
}
49+
}

0 commit comments

Comments
 (0)