如何从 HTML 或 JSX 中提取所有字符串常量?
How to extract all string constants from HTML or JSX?
编辑:我最终自己制作了一个名为 i18nize-react 的 babel 插件 CLI 工具:D
我正在尝试将现有的 React 应用程序从英语翻译成另一种语言。 JSX 中的所有字符串常量都是硬编码的。有没有一种简单的方法可以提取所有字符串常量并将它们转储到 .json
文件中?
这是我正在尝试做的一个例子。
// Original js file
class Component1 extends React.Component {
constructor(props){
super(props);
this.state = {
// ...
}
}
render(){
return(
<div>
Some Text
<p>
Some more text
<a href="/some/route">
Some link
</a>
</p>
</div>
)
}
}
STRINGS.json
{
"ENGLISH":{
"TEXT1":"Some Text",
"TEXT2":"Some more text",
"TEXT3":"Some link"
},
"OTHER_LANGUAGE":{
"TEXT1":"asfsadfasfd",
"TEXT2":"sadfsfd",
"TEXT3":"sdfsdfsfdfd"
}
}
新组件
// After the strings are extracted
import STRINGS from strings.json
class Component1 extends React.Component {
constructor(props){
super(props);
this.state = {
// ...
}
}
render(){
return(
<div>
{STRINGS[this.props.language].TEXT1}
<p>
{STRINGS[this.props.language].TEXT2}
<a href="/some/route">
{STRINGS[this.props.language].TEXT3}
</a>
</p>
</div>
)
}
}
您将要使用 javascript 抽象语法树解析器。一个流行的是 acorn, another one is espree。如果您使用的是 acorn,则需要 acorn-jsx
插件
这里有一个例子,它输出了你想要的 JSON 文件(虽然它是为 every 函数做的。如果你想更具体,你可以范围它到渲染函数):
const fs = require('fs');
const acorn = require('acorn-jsx-walk');
const walk = acorn.default;
const { MethodDefinition, Literal } = acorn.base;
const file = fs.readFileSync('./file.js', 'utf8');
const strings = [];
walk(file, {
Literal({ value }) {
strings.push(value.trim());
}
});
const ENGLISH = strings.reduce((acc, item, i) => {
acc[`TEXT${i+1}`] = item;
return acc;
}, {});
console.log(JSON.stringify({ ENGLISH }, null, 2));
returns:
{
"ENGLISH": {
"TEXT1": "Some Text",
"TEXT2": "Some more text",
"TEXT3": "Some link",
"TEXT4": "",
"TEXT5": ""
}
}
创建一个新的 javascript 文件更复杂,但它会涉及围绕 AST 添加逻辑,然后从中重新生成 javascript 文件。 (一旦您选择了要使用的工具,这可能值得一个单独的问题)
编辑:我最终自己制作了一个名为 i18nize-react 的 babel 插件 CLI 工具:D
我正在尝试将现有的 React 应用程序从英语翻译成另一种语言。 JSX 中的所有字符串常量都是硬编码的。有没有一种简单的方法可以提取所有字符串常量并将它们转储到 .json
文件中?
这是我正在尝试做的一个例子。
// Original js file
class Component1 extends React.Component {
constructor(props){
super(props);
this.state = {
// ...
}
}
render(){
return(
<div>
Some Text
<p>
Some more text
<a href="/some/route">
Some link
</a>
</p>
</div>
)
}
}
STRINGS.json
{
"ENGLISH":{
"TEXT1":"Some Text",
"TEXT2":"Some more text",
"TEXT3":"Some link"
},
"OTHER_LANGUAGE":{
"TEXT1":"asfsadfasfd",
"TEXT2":"sadfsfd",
"TEXT3":"sdfsdfsfdfd"
}
}
新组件
// After the strings are extracted
import STRINGS from strings.json
class Component1 extends React.Component {
constructor(props){
super(props);
this.state = {
// ...
}
}
render(){
return(
<div>
{STRINGS[this.props.language].TEXT1}
<p>
{STRINGS[this.props.language].TEXT2}
<a href="/some/route">
{STRINGS[this.props.language].TEXT3}
</a>
</p>
</div>
)
}
}
您将要使用 javascript 抽象语法树解析器。一个流行的是 acorn, another one is espree。如果您使用的是 acorn,则需要 acorn-jsx
插件
这里有一个例子,它输出了你想要的 JSON 文件(虽然它是为 every 函数做的。如果你想更具体,你可以范围它到渲染函数):
const fs = require('fs');
const acorn = require('acorn-jsx-walk');
const walk = acorn.default;
const { MethodDefinition, Literal } = acorn.base;
const file = fs.readFileSync('./file.js', 'utf8');
const strings = [];
walk(file, {
Literal({ value }) {
strings.push(value.trim());
}
});
const ENGLISH = strings.reduce((acc, item, i) => {
acc[`TEXT${i+1}`] = item;
return acc;
}, {});
console.log(JSON.stringify({ ENGLISH }, null, 2));
returns:
{
"ENGLISH": {
"TEXT1": "Some Text",
"TEXT2": "Some more text",
"TEXT3": "Some link",
"TEXT4": "",
"TEXT5": ""
}
}
创建一个新的 javascript 文件更复杂,但它会涉及围绕 AST 添加逻辑,然后从中重新生成 javascript 文件。 (一旦您选择了要使用的工具,这可能值得一个单独的问题)