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

Commit a4f85ab

Browse files
author
Long Ho
committed
feat(babel-plugin-react-intl): add outputEmptyJson option
This will suppress writing out empty files if file has no messages
1 parent 42e0242 commit a4f85ab

File tree

7 files changed

+95
-37
lines changed

7 files changed

+95
-37
lines changed

packages/babel-plugin-react-intl/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ If a message descriptor has a `description`, it'll be removed from the source af
6161

6262
- **`extractFromFormatMessageCall`**: Opt-in to extract from `intl.formatMessage` call with the same restrictions, e.g: has to be called with object literal such as `intl.formatMessage({ id: 'foo', defaultMessage: 'bar', description: 'baz'})`
6363

64+
- **`outputEmptyJson`**: output file with empty `[]` if src has no messages. For build systems like bazel that relies on specific output mapping, not writing out a file can cause issues.
65+
6466
### Via Node API
6567

6668
The extract message descriptors are available via the `metadata` property on the object returned from Babel's `transform()` API:

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ export default declare((api: any, options: OptionsSchema) => {
302302
name: 'babel-plugin-react-intl',
303303
baseDataPath: 'options',
304304
});
305-
const {messagesDir} = options;
305+
const {messagesDir, outputEmptyJson} = options;
306306

307307
/**
308308
* Store this in the node itself so that multiple passes work. Specifically
@@ -341,7 +341,7 @@ export default declare((api: any, options: OptionsSchema) => {
341341
const descriptors = Array.from(messages.values());
342342
state.metadata['react-intl'] = {messages: descriptors};
343343

344-
if (basename && messagesDir) {
344+
if (basename && messagesDir && (outputEmptyJson || descriptors.length)) {
345345
// Make sure the relative path is "absolute" before
346346
// joining it with the `messagesDir`.
347347
let relativePath = p.join(p.sep, p.relative(process.cwd(), filename));

packages/babel-plugin-react-intl/src/options.schema.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
},
1111
"removeDefaultMessage": {"type": "boolean"},
1212
"extractFromFormatMessageCall": {"type": "boolean"},
13-
"additionalComponentNames": {"type": "array", "items": {"type": "string"}}
13+
"additionalComponentNames": {"type": "array", "items": {"type": "string"}},
14+
"outputEmptyJson": {"type": "boolean"}
1415
},
1516
"additionalProperties": false
1617
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export interface OptionsSchema {
1313
removeDefaultMessage?: boolean;
1414
extractFromFormatMessageCall?: boolean;
1515
additionalComponentNames?: string[];
16+
outputEmptyJson?: boolean;
1617
}

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

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -270,40 +270,6 @@ Array [
270270
]
271271
`;
272272

273-
exports[`emit asserts for: output match: empty 1`] = `
274-
Object {
275-
"messages": Array [],
276-
}
277-
`;
278-
279-
exports[`emit asserts for: output match: empty 2`] = `
280-
"\\"use strict\\";
281-
282-
Object.defineProperty(exports, \\"__esModule\\", {
283-
value: true
284-
});
285-
exports.default = void 0;
286-
287-
var _react = _interopRequireWildcard(require(\\"react\\"));
288-
289-
var _macro = require(\\"@formatjs/macro\\");
290-
291-
function _getRequireWildcardCache() { if (typeof WeakMap !== \\"function\\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
292-
293-
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; }
294-
295-
class Foo extends _react.Component {
296-
render() {
297-
return _react.default.createElement(\\"div\\", null);
298-
}
299-
300-
}
301-
302-
exports.default = Foo;"
303-
`;
304-
305-
exports[`emit asserts for: output match: empty 3`] = `Array []`;
306-
307273
exports[`emit asserts for: output match: enforceDefaultMessage 1`] = `
308274
Object {
309275
"messages": Array [
@@ -586,6 +552,34 @@ Array [
586552
]
587553
`;
588554

555+
exports[`options outputEmptyJson should output empty files 1`] = `
556+
"\\"use strict\\";
557+
558+
Object.defineProperty(exports, \\"__esModule\\", {
559+
value: true
560+
});
561+
exports.default = void 0;
562+
563+
var _react = _interopRequireWildcard(require(\\"react\\"));
564+
565+
var _macro = require(\\"@formatjs/macro\\");
566+
567+
function _getRequireWildcardCache() { if (typeof WeakMap !== \\"function\\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
568+
569+
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; }
570+
571+
class Foo extends _react.Component {
572+
render() {
573+
return _react.default.createElement(\\"div\\", null);
574+
}
575+
576+
}
577+
578+
exports.default = Foo;"
579+
`;
580+
581+
exports[`options outputEmptyJson should output empty files 2`] = `Array []`;
582+
589583
exports[`options removeDefaultMessage should remove default message 1`] = `
590584
"\\"use strict\\";
591585
@@ -702,3 +696,29 @@ Array [
702696
},
703697
]
704698
`;
699+
700+
exports[`options without outputEmptyJson should output empty files 1`] = `
701+
"\\"use strict\\";
702+
703+
Object.defineProperty(exports, \\"__esModule\\", {
704+
value: true
705+
});
706+
exports.default = void 0;
707+
708+
var _react = _interopRequireWildcard(require(\\"react\\"));
709+
710+
var _macro = require(\\"@formatjs/macro\\");
711+
712+
function _getRequireWildcardCache() { if (typeof WeakMap !== \\"function\\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
713+
714+
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; }
715+
716+
class Foo extends _react.Component {
717+
render() {
718+
return _react.default.createElement(\\"div\\", null);
719+
}
720+
721+
}
722+
723+
exports.default = Foo;"
724+
`;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import React, {Component} from 'react';
2+
import {_} from '@formatjs/macro';
3+
4+
export default class Foo extends Component {
5+
render() {
6+
return <div></div>;
7+
}
8+
}

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const skipOutputTests = [
1919
'overrideIdFn',
2020
'removeDefaultMessage',
2121
'additionalComponentNames',
22+
'outputEmptyJson',
23+
'empty',
2224
];
2325

2426
const fixturesDir = join(__dirname, 'fixtures');
@@ -62,6 +64,30 @@ describe('options', () => {
6264
// Check message output
6365
expect(require(join(fixtureDir, 'actual.json'))).toMatchSnapshot();
6466
});
67+
it('outputEmptyJson should output empty files', function() {
68+
const fixtureDir = join(fixturesDir, 'outputEmptyJson');
69+
70+
const actual = transform(join(fixtureDir, 'actual.js'), {
71+
outputEmptyJson: true,
72+
})!.code;
73+
74+
// Check code output
75+
expect(trim(actual)).toMatchSnapshot();
76+
77+
// Check message output
78+
expect(require(join(fixtureDir, 'actual.json'))).toMatchSnapshot();
79+
});
80+
it('without outputEmptyJson should output empty files', function() {
81+
const fixtureDir = join(fixturesDir, 'empty');
82+
83+
const actual = transform(join(fixtureDir, 'actual.js'), {})!.code;
84+
85+
// Check code output
86+
expect(trim(actual)).toMatchSnapshot();
87+
88+
// Check message output
89+
expect(fs.existsSync(join(fixtureDir, 'actual.json'))).toBeFalsy();
90+
});
6591
it('correctly overrides the id when overrideIdFn is provided', () => {
6692
const fixtureDir = join(fixturesDir, 'overrideIdFn');
6793

0 commit comments

Comments
 (0)