ob-intl-cli(以下简称oic)是一个前端项目国际化工具,诞生于ODC开源过程中。 用于在开源过程中逐步替代在原有的国际化流程中所使用到的内部国际化框架 @ali/parrot-tool-must(以下简称must),oic所使用的配置文件与must基本保持一致,项目中原有的关于must的配置脚本,只需进行少量修改即可使用oic替代must进行项目的国际化。 如果你对前端国际化的实现流程不太熟悉的话,通过阅读该文档尾部关于前端国际化相关实现流程的介绍,你会对该流程有一个大概的认知。
- oic目前只支持(ts|js|tsx|jsx)等文件类型,因为OB前端团队这边基本都是用的React,所以目前没有支持vue或者其他类型的想法。
- oic目前不支持must中的hook功能。
- 收集已经弃用的国际化文案,并更新国际化产物。随着版本迭代,消费国际化产物的代码已经被修改,对应的文案已经弃用,但是仍存在于国际化产物中。这也使得国际化产物中存在大量冗余的弃用文案,oic可能会在后续的迭代中实现弃用文案的收集和清除。
以下是示例配置项
{
entry: path.resolve(process.cwd(), './src/examples/react-demo/src_other'),
sourceLang: 'zh-CN', // 默认简体中文
targetLang: 'en', // 默认英语,后面会支持多目标语言。
prettier: true, // 默认开启代码美化
exclude: (path) => { // 设置哪些文件或文件夹底下的源代码是不需要进行国际化处理的
return (
path.includes('src/.umi')
|| path.includes('src/locale')
|| path.includes('src/main')
); // 不处理 .umi 下的文件
},
// 这里是文案提取时所使用的提取函数,默认使用中文提取功能,开发者也可以自定义提取函数,用于开启特定文案的提取
matchCopy: matchText,
macro: {
// 同output
path: path.resolve(process.cwd(), './src/locale/must'),
// 国际化过程后,源代码中使用国际化文案的工具函数
method: `formatMessage({id: '$key$'})`,
import: "import { formatMessage } from '@/util/intl';\n", // 国际化过程中插入的用户的国际化
showComment: true, // 默认开启代码注释,在文案提取后会在原来的位置注释文案的内容
},
name: pkg.name,
sep: '.',
}
oic 执行的根目录。
Translate过程翻译文案的源语言,默认源语言为简体中文,既zh-CN
;
Translate过程翻译文案的目标语言,默认目标语言为英语,既en
;
目前只实现了string类型的参数的部分。
设置哪些文件或文件夹的源代码是不需要进行国际化处理的。
// 1. exclude: string;
// 例如'src/.umi',oic在执行过程中会自动跳过'src/.umi'底下的源代码。
// 2. exclude: string[];
// 例如 ['src/.umi', 'src/locale'],oic在执行过程中会跳过'src/.umi'及 'src/locale'底下的源代码。
// 3. exclude: function (originPath: string);
// 例如
// oic在执行过程中会跳过满足excludeFunction的文件路径下的源代码。
function excludeFunction (originPath) {
return originPath.includes('src/.umi');
};
配置是否开启代码美化,默认true。
Extract过程中提取文案所使用的筛选函数,默认提取简体中文。
const includeChinese = (code, nodePath) => {
return new RegExp('[\u{4E00}-\u{9FFF}]', 'g').test(code);
}
Transfrom过程中会使用到的相关配置参数: 1.path: string; 配置Generate过程后生成产物的存放路径。例如
{
path: path.resolve(process.cwd(), './src/locale/must'),
}
2.method: string;
配置Transform过程中注入AST中的调用国际化产物的函数。
例如: formatMessage({id: '$key$'})
。
oic会提取该配置项,将GenerateKey过程中生成的对应的key注入,并根据不同的AST结点类型生成不同的注入内容。
<div>{ formatMessage({ id: 'xxxx.xxxx.xxxx.xxxx'}) } </div>
3.import: string; Generate过程后注入源文件头部的依赖路径,oic会自动识别该源代码文件中是否已经注入过该依赖,避免重复注入。
4.showComment: boolean; 配置开启文案注释功能,默认开启,将在注入method的位置一并注入注释文本。
配置此项,将会额外添加信息在GenerateKey生成的key的首部,通常是package.json中的name,默认为空。
配置此项,将会修改GenerateKey过程中生成的key所使用的路径分隔符,默认使用.。
- 可以在代码首部使用 // @oic-file-ignore 来提示oic跳过该文件。
- 可以在代码首部使用 // @oic-line-ignore 来提示oic跳过下一行代码中的文案。
- 使用babel.parse解析源文件中的源码后,我们会得到一棵抽象语法树(Abstract syntax tree, 既AST),既下图中的Parse过程;
- 通常一些babel插件或者工具会通过@babel/traverse来遍历AST上的每个节点,对节点进行若干处理后,你会将原有的AST改造成一棵新的AST,既下图中的Transform过程;
- 将经Transform过程生成的新的AST交由@babel/generator处理,假如Transform过程中你的操作是合理且正确的,你将在Generate过程后得到一份被改造过的代码;
而oic也是基于以上流程实现的前端国际化。 我们在Transform的过程中会进行目标文案的提取收集(Extract)、批量翻译(Translate)生成语义性和辨识性较高的key(GenerateKey)、对原有的AST进行用户的配置注入和改造(Inject)。 最后用Generate过程后生成的代码替代源文件中的代码,通常在完成以上步骤之后,我们还会对代码进行一定程度的代码美化工作,既Prettier。
注:此图来自网络文章[Revealing the magic of AST by writing babel plugins]:https://dev.to/viveknayyar/revealing-the-magic-of-ast-by-writing-babel-plugins-1h01