Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jun 8, 2019. It is now read-only.

Commit95d9121

Browse files
jouallonglho
authored andcommitted
Add overrideIdFn option to allow manipulation of IDs during extraction (#162)
* feat: add overrideIdFn option to allow manipulation of IDs during extractions* lint: add semi-colon
1 parentfc4dddd commit95d9121

File tree

6 files changed

+174
-5
lines changed

6 files changed

+174
-5
lines changed

‎README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Extracts string messages for translation from modules that use [React Intl][].
55

66
###React Intl
77
This Babel plugin works with React Intl v2.x
8-
8+
99
###Babel
1010
-**3.x** of this plugin works with Babel 7
1111
-**2.x** works with Babel 6
@@ -49,6 +49,8 @@ If a message descriptor has a `description`, it'll be removed from the source af
4949

5050
-**`moduleSourceName`**: The ES6 module source name of the React Intl package. Defaults to:`"react-intl"`, but can be changed to another name/path to React Intl.
5151

52+
-**`overrideIdFn`**: A function with the signature`(id: string, defaultMessage: string, description: string|object) => string` which allows you to override the ID both in the extracted javascript and messages.
53+
5254
###Via Node API
5355

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

‎src/index.js‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export default function ({types: t}) {
101101
},{});
102102
}
103103

104-
functionevaluateMessageDescriptor({...descriptor},{isJSXSource=false}={}){
104+
functionevaluateMessageDescriptor({...descriptor},{isJSXSource=false, overrideIdFn}={}){
105105
Object.keys(descriptor).forEach((key)=>{
106106
constvaluePath=descriptor[key];
107107

@@ -112,6 +112,10 @@ export default function ({types: t}) {
112112
}
113113
});
114114

115+
if(overrideIdFn){
116+
descriptor.id=overrideIdFn(descriptor.id,descriptor.defaultMessage,descriptor.description);
117+
}
118+
115119
returndescriptor;
116120
}
117121

@@ -275,16 +279,18 @@ export default function ({types: t}) {
275279
// context, then store it.
276280
descriptor=evaluateMessageDescriptor(descriptor,{
277281
isJSXSource:true,
282+
overrideIdFn:opts.overrideIdFn,
278283
});
279284

280285
storeMessage(descriptor,path,state);
281286

282287
// Remove description since it's not used at runtime.
283-
attributes.some((attr)=>{
288+
attributes.forEach((attr)=>{
284289
constketPath=attr.get('name');
285290
if(getMessageDescriptorKey(ketPath)==='description'){
286291
attr.remove();
287-
returntrue;
292+
}elseif(opts.overrideIdFn&&getMessageDescriptorKey(ketPath)==='id'){
293+
attr.get('value').replaceWith(t.stringLiteral(descriptor.id));
288294
}
289295
});
290296

@@ -297,6 +303,7 @@ export default function ({types: t}) {
297303
CallExpression(path,state){
298304
constmoduleSourceName=getModuleSourceName(state.opts);
299305
constcallee=path.get('callee');
306+
const{opts}=state;
300307

301308
functionassertObjectExpression(node){
302309
if(!(node&&node.isObjectExpression())){
@@ -326,7 +333,7 @@ export default function ({types: t}) {
326333
);
327334

328335
// Evaluate the Message Descriptor values, then store it.
329-
descriptor=evaluateMessageDescriptor(descriptor);
336+
descriptor=evaluateMessageDescriptor(descriptor,{overrideIdFn:opts.overrideIdFn});
330337
storeMessage(descriptor,messageObj,state);
331338

332339
// Remove description since it's not used at runtime.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
importReact,{Component}from'react';
2+
import{defineMessages,FormattedMessage,FormattedHTMLMessage}from'react-intl';
3+
4+
constmsgs=defineMessages({
5+
header:{
6+
id:'foo.bar.baz',
7+
defaultMessage:'Hello World!',
8+
description:'The default message',
9+
},
10+
content:{
11+
id:'foo.bar.biff',
12+
defaultMessage:'Hello Nurse!',
13+
description:{
14+
text:'Something for the translator.',
15+
metadata:'Additional metadata content.',
16+
},
17+
},
18+
});
19+
20+
exportdefaultclassFooextendsComponent{
21+
render(){
22+
return(
23+
<div>
24+
<h1><FormattedMessage{...msgs.header}/></h1>
25+
<p><FormattedMessage{...msgs.content}/></p>
26+
<FormattedMessage
27+
id='foo.bar.zoo'
28+
defaultMessage='Hello World!'
29+
description={{
30+
text:'Something for the translator. Another description',
31+
metadata:'Additional metadata content.',
32+
}}
33+
/>
34+
<FormattedHTMLMessage
35+
id='foo.bar.delta'
36+
defaultMessage='<h1>Hello World!</h1>'
37+
description='The default message.'
38+
/>
39+
</div>
40+
);
41+
}
42+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"use strict";
2+
3+
Object.defineProperty(exports,"__esModule",{
4+
value:true
5+
});
6+
exports.default=void0;
7+
8+
var_react=_interopRequireWildcard(require("react"));
9+
10+
var_reactIntl=require("react-intl");
11+
12+
function_interopRequireWildcard(obj){if(obj&&obj.__esModule){returnobj;}else{varnewObj={};if(obj!=null){for(varkeyinobj){if(Object.prototype.hasOwnProperty.call(obj,key)){vardesc=Object.defineProperty&&Object.getOwnPropertyDescriptor ?Object.getOwnPropertyDescriptor(obj,key) :{};if(desc.get||desc.set){Object.defineProperty(newObj,key,desc);}else{newObj[key]=obj[key];}}}}newObj.default=obj;returnnewObj;}}
13+
14+
function_typeof(obj){if(typeofSymbol==="function"&&typeofSymbol.iterator==="symbol"){_typeof=function_typeof(obj){returntypeofobj;};}else{_typeof=function_typeof(obj){returnobj&&typeofSymbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype ?"symbol" :typeofobj;};}return_typeof(obj);}
15+
16+
function_classCallCheck(instance,Constructor){if(!(instanceinstanceofConstructor)){thrownewTypeError("Cannot call a class as a function");}}
17+
18+
function_defineProperties(target,props){for(vari=0;i<props.length;i++){vardescriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"indescriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}
19+
20+
function_createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);returnConstructor;}
21+
22+
function_possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeofcall==="function")){returncall;}return_assertThisInitialized(self);}
23+
24+
function_assertThisInitialized(self){if(self===void0){thrownewReferenceError("this hasn't been initialised - super() hasn't been called");}returnself;}
25+
26+
function_getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf ?Object.getPrototypeOf :function_getPrototypeOf(o){returno.__proto__||Object.getPrototypeOf(o);};return_getPrototypeOf(o);}
27+
28+
function_inherits(subClass,superClass){if(typeofsuperClass!=="function"&&superClass!==null){thrownewTypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_setPrototypeOf(subClass,superClass);}
29+
30+
function_setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function_setPrototypeOf(o,p){o.__proto__=p;returno;};return_setPrototypeOf(o,p);}
31+
32+
varmsgs=(0,_reactIntl.defineMessages)({
33+
header:{
34+
"id":"HELLO.foo.bar.baz.12.string",
35+
"defaultMessage":"Hello World!"
36+
},
37+
content:{
38+
"id":"HELLO.foo.bar.biff.12.object",
39+
"defaultMessage":"Hello Nurse!"
40+
}
41+
});
42+
43+
varFoo=
44+
/*#__PURE__*/
45+
function(_Component){
46+
_inherits(Foo,_Component);
47+
48+
functionFoo(){
49+
_classCallCheck(this,Foo);
50+
51+
return_possibleConstructorReturn(this,_getPrototypeOf(Foo).apply(this,arguments));
52+
}
53+
54+
_createClass(Foo,[{
55+
key:"render",
56+
value:functionrender(){
57+
return_react.default.createElement("div",null,_react.default.createElement("h1",null,_react.default.createElement(_reactIntl.FormattedMessage,msgs.header)),_react.default.createElement("p",null,_react.default.createElement(_reactIntl.FormattedMessage,msgs.content)),_react.default.createElement(_reactIntl.FormattedMessage,{
58+
id:"HELLO.foo.bar.zoo.12.object",
59+
defaultMessage:"Hello World!"
60+
}),_react.default.createElement(_reactIntl.FormattedHTMLMessage,{
61+
id:"HELLO.foo.bar.delta.21.string",
62+
defaultMessage:"<h1>Hello World!</h1>"
63+
}));
64+
}
65+
}]);
66+
67+
returnFoo;
68+
}(_react.Component);
69+
70+
exports.default=Foo;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[
2+
{
3+
"id":"HELLO.foo.bar.baz.12.string",
4+
"description":"The default message",
5+
"defaultMessage":"Hello World!"
6+
},
7+
{
8+
"id":"HELLO.foo.bar.biff.12.object",
9+
"description": {
10+
"text":"Something for the translator.",
11+
"metadata":"Additional metadata content."
12+
},
13+
"defaultMessage":"Hello Nurse!"
14+
},
15+
{
16+
"id":"HELLO.foo.bar.zoo.12.object",
17+
"description": {
18+
"text":"Something for the translator. Another description",
19+
"metadata":"Additional metadata content."
20+
},
21+
"defaultMessage":"Hello World!"
22+
},
23+
{
24+
"id":"HELLO.foo.bar.delta.21.string",
25+
"description":"The default message.",
26+
"defaultMessage":"<h1>Hello World!</h1>"
27+
}
28+
]

‎test/index.js‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const skipTests = [
1717
'moduleSourceName',
1818
'icuSyntax',
1919
'removeDescriptions',
20+
'overrideIdFn',
2021
];
2122

2223
constfixturesDir=path.join(__dirname,'fixtures');
@@ -62,6 +63,25 @@ describe('options', () => {
6263
}
6364
});
6465

66+
it('correctly overrides the id when overrideIdFn is provided',()=>{
67+
constfixtureDir=path.join(fixturesDir,'overrideIdFn');
68+
69+
constactual=transform(path.join(fixtureDir,'actual.js'),{
70+
overrideIdFn:(id,defaultMessage,description)=>{
71+
return`HELLO.${id}.${defaultMessage.length}.${typeofdescription}`;
72+
},
73+
});
74+
75+
// Check code output
76+
constexpected=fs.readFileSync(path.join(fixtureDir,'expected.js'));
77+
assert.equal(trim(actual),trim(expected));
78+
79+
// Check message output
80+
constexpectedMessages=fs.readFileSync(path.join(fixtureDir,'expected.json'));
81+
constactualMessages=fs.readFileSync(path.join(fixtureDir,'actual.json'));
82+
assert.equal(trim(actualMessages),trim(expectedMessages));
83+
});
84+
6585
it('allows no description when enforceDescription=false',()=>{
6686
constfixtureDir=path.join(fixturesDir,'enforceDescriptions');
6787

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp