前言
这个标题可能是我掘金看多了,第一反应就是这个。。。🐶
效果图
背景
最近在做一个国际化的站点,网页上显示的文案都需要使用formatjs进行转换
当语言文件的内容一多起来了就不知道自己取的key叫什么了
然后再去翻译文件中进行搜索,然后复制粘贴,浪费了不少时间
插件设计
需求
在网上找了几款vscode插件发现与自己需求还是有一定差距
我需要的核心功能是,输入key和value都有提示,且只用加载一个默认语言文件即可(和视觉稿保持一致)
// en.json
{
"common.submit": "submit",
"common.delete_msg": "are you sure ?"
}
例如当我输入 common.delete的时候会出现提示
输入 are you 相关的词汇时也会提示
所以我第一版本的功能如下
- 提供一个默认的语言文件地址如
src/lang/en.json - 加载指定配置的文件,监听用户输入,当
en.json的key或者value和用户输入匹配则返回 - 监听默认文件的
change事件,确保用户新增的内容正常响应
开始开发
下载脚手架
下载开发所需的脚手架,可以快速生成基础代码
npm install -g yo generator-code
配置插件的启动方式
vscode插件的启动方式有很多种,其它教程常见的就是命令启动
// package.json
"activationEvents": [
"onCommand:formatjs-tool-vscode.helloWorld"
],
"contributes": {
"commands": [{
{
"command": "formatjs-tool-vscode.helloWorld",
"title": "Hello World"
}
}]
},
通过Ctrl+Shift+P组合键唤醒Command Palette 然后输入上面配置的title对应的内容
回车之后就能启动了
这里我不需要使用命令启动,需要在指定类型的JS文件中启动 js、ts、jsx、tsx
// package.json
"activationEvents": [
"onLanguage:javascript",
"onLanguage:typescript",
"onLanguage:javascriptreact",
"onLanguage:typescriptreact"
]
事件注册
vscode支持的事件有很多,这里我们只需要在用户输入的时候给出对应的提示就好
这里使用 vscode.languages.registerCompletionItemProvider来注册事件即可
exports.activate = function(context) {
const triggers = [' '];
getLangData(); // 获取 .formatool.json文件配置默认语言文件数据
const completionProvider = vscode.languages.registerCompletionItemProvider(LANGUAGES, {
async provideCompletionItems(document, position, token, context) {
return locale;
}
}, ...triggers);
context.subscriptions.push(completionProvider);
}
核心代码
核心逻辑就是读取用户配置的json文件内容,并在其修改时更新数据
并且key和value作为提示内容,这里只需要遍历en.json时把key和value都塞入提示数据中即可
读取数据
const getLangData = async ()=>{
const configPath = path.resolve(vscode.workspace.rootPath,CONFIG_PATH)
if(!fs.existsSync(configPath)){
return
}
const configData = await getFileData(configPath);
if(!configData.defaultPath){
return
}
locale = [];
const langPath = path.resolve(vscode.workspace.rootPath,configData.defaultPath);
watchFileChange(langPath); // 监听数据修改
const data = await getFileData(langPath)
// key和value都塞入数据中
Object.entries(data).forEach(([k,v])=>{
locale.push({label:k,detail:v,insertText:`{formatMessage({id:'${k}'})}`,documentation:v, filterText: k})
locale.push({label:v,detail:v,insertText:`{formatMessage({id:'${k}'})}`,documentation:v, filterText: v})
})
}
监听文件修改
文件修改时重新读取数据即可
const watchFileChange = (path)=>{
fs.watch(path,(event,filename)=>{
if(event === "change") getLangData()
})
}
调试、打包、发布
这里网上教程一堆,就不重复了
总结
这个乞丐版的vscode插件终于完成了
只能说满足部分的开发场景,还有很多事情能做的
- 通过命令转化表格为json语言文件(产品提供的在线表格),并按照规则生成key
- 自定义生成模版内容
formatMessage - 点击语言提示跳转对应语言文件并定位到行
希望能给一些同学提供一个解决问题的思路
如果喜欢可以点个star 👉 github