受够了多语言的复制粘贴,我写了一个vscode插件

1,549 阅读3分钟

前言

这个标题可能是我掘金看多了,第一反应就是这个。。。🐶

效果图

效果图.gif

背景

最近在做一个国际化的站点,网页上显示的文案都需要使用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.jsonkey或者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对应的内容
回车之后就能启动了

image.png

这里我不需要使用命令启动,需要在指定类型的JS文件中启动 jstsjsxtsx

   // 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文件内容,并在其修改时更新数据
并且keyvalue作为提示内容,这里只需要遍历en.json时把keyvalue都塞入提示数据中即可

读取数据

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插件终于完成了
只能说满足部分的开发场景,还有很多事情能做的

  1. 通过命令转化表格为json语言文件(产品提供的在线表格),并按照规则生成key
  2. 自定义生成模版内容 formatMessage
  3. 点击语言提示跳转对应语言文件并定位到行

希望能给一些同学提供一个解决问题的思路
如果喜欢可以点个star 👉 github