1. 起因
国际化是我们目前开发工作中非常重要的一环。对于老项目,我们可以通过便捷的方式对中文文案进行批量国际化;但是对于新增的功能或者模块开发,一般还是开发同学对文案逐个进行国际化。我自己的开发流程一般是这样的:
开发中直接写上中文(1) -> 功能开发完成后开始做国际化(2) -> 找到中文文案(3)-> 美杜莎创建key(4) -> 美杜莎文案翻译(5) -> 代码中增加该translationKey(6) -> 给该key添加注释(对应的中文)(7)-> 复制key (8)-> 再找回刚刚中文文案的位置(9) -> 粘贴key,替换中文(10) -> 下个文案同流程处理,重复(3)。
可以看出这个过程相当的繁琐,存在很多复制粘贴的步骤,那么是否可以通过一些方式来省去这些人肉的操作,更省力一点呢? 由此,我想可以搞个简单的VSCode插件来将(8~10)这几步简化下,基本思路是选中中文文案后,可以自动将文案替换成对应的key,这样就无需反复复制粘贴。
下文主要讲下我学习和开发插件的过程以及最终效果。
2. VSCode插件实现
2.1 初始化
2.1.1 脚手架
为方便开发,微软提供了vscode插件的代码生成器,我们可以使用Yeoman来快速项目脚手架,如下:
npm install -g yo generator-code
yo code
运行后,会看到如下提示:
到此我们的项目就初始化完成了,可以简单看下工程结构
2.1.2 工程结构
如下图所示,其中extension.ts
和package.json
是我们主要关注的两个文件。
2.2 开发
首先我们看下extension.ts
这个文件的实现:
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "test" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
let disposable = vscode.commands.registerCommand('test.helloWorld', () => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
vscode.window.showInformationMessage('Hello World from test!');
});
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
export function deactivate() {}
其中的核心部分是注册命令即registerCommand
部分,这个方法注册了一个可执行的命令,第二个参数是对应的具体实现。
这样看来,我只需要在17行对应的部分将选中文案并自动替换的部分实现,就可以达成我想要的效果了。(^-^)V
我们分三步走:
- 编写代码,获取选中的中文文案
- 解析项目中的translationKeys.js文件,获取该段中文文案对应的key
- 替换选中的文案,改为
i18next.t('xxx')
的写法
2.2.1 编写代码,获取选中的中文文案
如下图所示,VS Code提供了如下api,可以用于注册文本编辑相关的命令。
回调方法的入参是TextEditor和TextEditorEdit,可以通过前者获取到当前选中区域的信息;通过后者对选取内容进行编辑等操作。如下所示:
textEditor.document.getText(textEditor.selection)
2.2.2 解析项目中的translationKeys.js文件
VSCode提供了api可以让我们访问到项目中的根目录,我们通过文件路径,读取到文件内容,就可以进行解析了。
const translationKeyFilePath = vscode.workspace.rootPath + '/translationKeys.js';
const translationKeysContent = fs.readFileSync(translationKeyFilePath, 'utf8');
再来看下我们的translationKey的文件,长这样子:
module.exports = [
"failed",//未通过
"unauthorized",//未授权
"certification_upgraded_tips",//员工「实名认证」升级为「实人认证」,更安全
"certification_upgraded_tips_self",//「实名认证」升级为「实人认证」,发现你未通过实人认证,请重新认证
"passed",//已通过
"real_certification",//实人认证
];
维护了一个translationKey的数组,每个元素后,是其对应的中文文案的注释。为了方便我们第三步的替换,这里我们需要生成一个key和中文的map映射表,常规处理即可,得到
// 中文及其对应的key的map
const translationKeysMap = {
"已通过": "passed",
"未通过": "failed",
}
2.2.3 替换选中的文案
第二步中我们已经得到了处理好的map,这里只需要将文本选取中的内容进行替换即可,非常简单,如下所示:
const translationKey = translationKeysMap[textEditor.document.getText(textEditor.selection)];
edit.replace(textEditor.selection, `{i18next.t('${translationKey}')}`)
2.2.4 配置
开发完成后,还需要在package.json中进行一些配置,才能在编辑器中使用这个命令。如下:
"activationEvents": [
"onCommand:extension.i18n-tool"
],
"contributes": {
"commands": [
{
"command": "extension.i18n-tool",
"title": "快速翻译文案"
}
],
"menus": {
"editor/context": [
{
"when": "editorHasSelection",
"command": "extension.i18n-tool",
"group": "6_Starling"
}
]
}
},
2.3 调试
开发过程中,调试是至关重要的一部分,VS Code插件的调试,只需要点击左侧的「运行」按钮运行即可。会自动唤起一个新的VSCode窗口,测试你的插件功能。
2.4 发布
看这里:https://code.visualstudio.com/api/working-with-extensions/publishing-extension
至此,我们完成了插件的开发和发布,可以来看下插件效果~
3. 插件效果
https://www.zhihu.com/video/1251526103782150144
使用了这个插件后,我的文案国际化流程调整为了:
开发中直接写上中文(1) -> 功能开发完成后开始做国际化(2) -> 找到中文文案(3)-> 美杜莎创建key(4) -> 美杜莎文案翻译(5) -> 代码中增加该translationKey(6) -> 给该key添加注释(对应的中文)(7)-> 下个文案同流程处理,重复(3)-> 自动替换文案
涉及到的文案越多,这个方式越省时省力~
4. 参考
https://code.visualstudio.com/api/references/vscode-api
以上完成了一个非常简陋版本的文案国际化的VSCode插件开发,对应我自己的开发效率来说,有一定的提升。但是当然这个插件还有许多不完善的地方,比如无法针对带变量的文案做处理,没有实现批量替换,也没有自动引入i18next库等等,后续还是要不断优化。
另外这次实践也只探得VSCode插件能力的其中一二,还有很多其他的强大能力没有涉及到,欢迎大家一起交流、学习~~