什么是ob-intl-cli
ob-intl-cli(以下简称oic)是一个前端项目国际化工具,诞生于ODC开源过程中。
用于在开源过程中逐步替代在原有的国际化流程中所使用到的内部国际化框架 @ali/parrot-tool-must(以下简称must),oic所使用的配置文件与must基本保持一致,项目中原有的关于must的配置脚本,只需进行少量修改即可使用oic替代must进行项目的国际化。
如果你对前端国际化的实现流程不太熟悉的话,通过阅读该文档尾部关于前端国际化相关实现流程的介绍,你会对该流程有一个大概的认知。
一、 ob-intl-cli有哪些不足/不支持的功能
- oic目前只支持(ts|js|tsx|jsx)等文件类型,因为OB前端团队这边基本都是用的React,所以目前没有支持vue或者其他类型的想法。
- oic目前不支持must中的hook功能。
二、 ob-intl-cli未来可能实现/支持的特性
- 收集已经弃用的国际化文案,并更新国际化产物。随着版本迭代,消费国际化产物的代码已经被修改,对应的文案已经弃用,但是仍存在于国际化产物中。这也使得国际化产物中存在大量冗余的弃用文案,oic可能会在后续的迭代中实现弃用文案的收集和清除。
三、 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')
);
},
matchCopy: matchText,
macro: {
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: '.',
}
1. entry: string;
oic 执行的根目录。
2. sourceLang: string;
Translate过程翻译文案的源语言,默认源语言为简体中文,既zh-CN
;
3. targetLang: string | string[];
Translate过程翻译文案的目标语言,默认目标语言为英语,既en
;
目前只实现了string类型的参数的部分。
4. exclude: string | string[] | function(originPath: string): boolean;
设置哪些文件或文件夹的源代码是不需要进行国际化处理的。
function excludeFunction (originPath) {
return originPath.includes('src/.umi');
};
5. prettier: boolean;
配置是否开启代码美化,默认true。
6. matchCopy: function(codeStr: string; nodePath: NodePath;): boolean;
Extract过程中提取文案所使用的筛选函数,默认提取简体中文。
const includeChinese = (code, nodePath) => {
return new RegExp('[\u{4E00}-\u{9FFF}]', 'g').test(code);
}
7. macro: MarcoOptions;
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的位置一并注入注释文本。
8. name: string;
配置此项,将会额外添加信息在GenerateKey生成的key的首部,通常是package.json中的name,默认为空。
9. sep: string;
配置此项,将会修改GenerateKey过程中生成的key所使用的路径分隔符,默认使用.。
四、 使用ob-intl-cli的过程中
- 你可以通过在代码首部使用// @i18n-ignore来提示oic跳过该文件。
五、 对于前端项目国际化,前端开发者需要了解的知识点
babel插件/库对源代码进行处理的大致流程
- 使用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