写个vscode插件, 帮助阅读i18n项目的代码
回复 交流 ,加入前端编程面试算法每日一题群
面试官也在看的前端面试资料
写个vscode插件, 帮助阅读i18n项目的代码

介绍
作者当前参与的项目是面向全球用户的, 项目免不了要做国际化处理, 哪怕只是一个简单的 ok按钮
的 ok文案
都要翻译成不同国家的语言展示, 所以在代码里面往往我们不可以直接命名为 ok
, 而是可能命名为 user_base_plan_edit_ok_button
这类的名字, 并且为了区分 i18n
与其它命名, 我们团队会采用全大写的方式类似 USER_BASE_PLAN_EDIT_OK_BUTTON
, 而这样的代码多了之后阅读起来会让 眼睛干涩
, 类似下面图里的伪代码:

为了解决这个 不好阅读
的问题我比较预期的效果是, 当鼠标悬浮在目标文字身上时会浮现出一个弹框, 而这个弹框至少要告诉我这个词语的中文或英文意思, 效果如下:

可以看出这个插件如果做好了不一定只能用在 i18n
这个只是点上, 可以用在很多方面, 比如某个code 103993283
这个code具体代表什么含义可以做个插件展示出来。
一: 初始化vscode项目
没做过vscode插件的同学推荐先读读我写的入门教程:
-
记一次前端"vscode插件编写实战"超详细的分享会(建议收藏哦)(上篇)
-
记一次前端"vscode插件编写实战"超详细的分享会(建议收藏哦)(下篇)
这次做的插件是针对我当前工程的, 没有广泛应用能力所以就没发布到vscode官方, 开发好后打包发到公司内网与群里就ok了。
创建项目: 这里项目名暂定叫 i18n2c
yo code

二: 初始化架构
extension.js
文件我们清理干净:
const vscode = require("vscode"); function activate(context) { vscode.window.showInformationMessage("i18n翻译插件加载完成"); } module.exports = { activate, };
修改 package.json
文件: 设置当资源加载完就开始加载我们的插件
{ // ... "activationEvents": [ "onStartupFinished" ], // ... }
点击 f5
开启调试模式, 出现下图就证明插件可以正常启动了:

三: 初始化hover文件
我们把 hover
后的逻辑都放在src里面:

简单改造一下 extension.js
, 把hover方法加进去:
const vscode = require("vscode"); const hover = require("./src/hover"); function activate(context) { vscode.window.showInformationMessage("i18n翻译插件加载完成"); context.subscriptions.push(hover); } module.exports = { activate, };
hover.js
导出悬停时的处理方法
const vscode = require("vscode"); module.exports = vscode.languages.registerHoverProvider("*", { provideHover(document, position) { return new vscode.Hover(`i18n插件前来助你渡劫`); }, });
当你悬停在任何位置的时候效果如下:

四: i18n目标文案的识别
每个团队的技术方案都不一样, 这里我只针对我们团队的方案进行设计, 希望起到一个抛砖引玉的目的:
我们团队的 i18n文案
都是大写, 并且使用 下划线
相互链接, 而我发现全局除了 i18n文案
外没有字符串里超过三个 下划线
, 并且 i18n文案
至少四个 下划线
, 所以当前我使用的是判断字符串里面是否含有超过三个 '_'
。
const vscode = require("vscode"); module.exports = vscode.languages.registerHoverProvider("*", { provideHover(document, position) { const word = document.getText(document.getWordRangeAtPosition(position)); if (word.split("_").length > 3) { return new vscode.Hover(`i18n插件前来助你渡劫`); } }, });
上面的 word
就是我们获取到的 被悬停的文本
五: 如何翻译成中文
上面我们找到了 要被翻译
的文案, 这里我们就要研究如何翻译这个文案了, 一般针对i18n都会有个翻译的字典包, 我们团队的就是一个 json文件
, 不同的是每个key是小写的, 大致的样子如下:

我要做的就是读取这个文件, 然后将 要被翻译
的文案转换为小写, 再去匹配一下就ok了。
const vscode = require("vscode"); const fs = require("fs"); module.exports = vscode.languages.registerHoverProvider("*", { provideHover(document, position) { const word = document.getText(document.getWordRangeAtPosition(position)); let jsonCN = JSON.parse( fs.readFileSync("/xxxx/xxxxx/langs/zh-CN.json") ); if (word.split("_").length > 3) { return new vscode.Hover(`i18n插件前来助你渡劫: - 中文: ${jsonCN[word.toLocaleLowerCase()]} `); } }, });

我们的 i18n字典
都是放在同一个文件夹里面的, 所以我只需要知道这个文件夹即可, 默认取出里面的中文与英文文案, 改造一下吧。
const vscode = require("vscode"); const fs = require("fs"); module.exports = vscode.languages.registerHoverProvider("*", { provideHover(document, position) { const word = document.getText(document.getWordRangeAtPosition(position)); if (word.split("_").length > 3) { const i18nPath = "/xxxx/xxxxx/langs"; const jsonUrlCN = i18nPath + "/zh-CN.json"; const jsonUrlEN = i18nPath + "/en.json"; let jsonCN = JSON.parse(fs.readFileSync(jsonUrlCN)); let jsonEN = JSON.parse(fs.readFileSync(jsonUrlEN)); return new vscode.Hover(`i18n插件前来助你渡劫: - 中文: ${jsonCN[word.toLocaleLowerCase()]} - 英文: ${jsonEN[word.toLocaleLowerCase()]} `); } }, });

这里的 i18nPath
当然可以由用户来配置啦, 接下来我们就把它研究。
六: setting配置
我们翻译字典文件所在的位置肯定不能 写死
在插件里面, 很多时候需要用户自己来设置, 这时我们就需要vscode的setting的概念了, 具体如下图所示:

第一步: 初始化配置项
我们来到 package.json
文件添加 setting
配置项:
{ "contributes": { "configuration": { "type": "object", "title": "i18n翻译配置", "properties": { "vscodePluginI18n.i18nPath": { "type": "string", "default": "", "description": "翻译文件的位置" }, "vscodePluginI18n.open": { "type": "boolean", "default": true, "description": "开启18n翻译" } } } }, }
type
设置为 布尔
会自动生成 CheckBox
还挺方便的。
第二步: 初始插件读取配置
extension.js
文件:
const vscode = require("vscode"); function activate(context) { const i18nPath = vscode.workspace .getConfiguration() .get("vscodePluginI18n.i18nPath"); const open = vscode.workspace.getConfiguration().get("vscodePluginI18n.open"); if (open && i18nPath) { vscode.window.showInformationMessage("i18n翻译插件已就位"); const hover = require("./src/hover"); context.subscriptions.push(hover); } } module.exports = { activate, };
这里要注意, 如果 const hover = require("./src/hover");
写在最上方, 可能会导致无法关闭悬停翻译效果, 这个里面有坑我们一会详细说说。
第三步: 悬停时读取路径
hover.js
文件:
const vscode = require("vscode"); const fs = require("fs"); module.exports = vscode.languages.registerHoverProvider("*", { provideHover(document, position) { const i18nPath = vscode.workspace .getConfiguration() .get("vscodePluginI18n.i18nPath"); const open = vscode.workspace .getConfiguration() .get("vscodePluginI18n.open"); if (i18nPath && open) { const word = document.getText(document.getWordRangeAtPosition(position)); if (word.split("_").length > 3) { const i18nPath = "/xxxxx/xxxx/langs"; const jsonUrlCN = i18nPath + "/zh-CN.json"; const jsonUrlEN = i18nPath + "/en.json"; let jsonCN = JSON.parse(fs.readFileSync(jsonUrlCN)); let jsonEN = JSON.parse(fs.readFileSync(jsonUrlEN)); return new vscode.Hover(`i18n插件前来助你渡劫: - 中文: ${jsonCN[word.toLocaleLowerCase()]} - 英文: ${jsonEN[word.toLocaleLowerCase()]} `); } } }, });
七: 何时判断是否开启插件
如果在 extension.js
文件里面引入了 hover
模块, 则就算我们判断了用户未开启 i18n翻译
流程也会走到hover模块, 但是如果我们在判断用户是否开启 i18n翻译
后进行引入 hover
模块就会造成, 如果用户改变配置开始翻译无法及时响应, 需要用户重启一下, 所以具体这里如何设计需要大家酌情啦。
八: 提示弹框
如果用户开启了 i18n翻译
但是没配置路径, 那么我们其实可以出现一个弹框提示用户是否要来填写这个翻译字典的路径, 类似下图的效果:

extension.js
文件里面使用 showInformationMessage
这个方法, 但是要增加两个参数:
const vscode = require("vscode"); function activate(context) { const i18nPath = vscode.workspace .getConfiguration() .get("vscodePluginI18n.i18nPath"); const open = vscode.workspace.getConfiguration().get("vscodePluginI18n.open"); if (open && i18nPath) { vscode.window.showInformationMessage("i18n翻译插件已就位"); const hover = require("./src/hover"); context.subscriptions.push(hover); } else if (open && !i18nPath) { vscode.window .showInformationMessage("是否设置翻译文件路径", "是", "否") .then((result) => { if (result === "是") { } }); } } module.exports = { activate, };
九: 选择文件
当用户点击'是'的时候我们需要借助vscode提供的api进行文件的选择, 并且拿到文件的返回值进行主动的设置操作:
vscode.window.showOpenDialog
方法, 他有四个主要的参数:
-
canSelectFiles
是否可选文件 -
canSelectFolders
是否可选文件夹 -
canSelectMany
是否可以多选 -
openLabel
提示文案 -
返回值是数组, 第一个元素的path属性, 就是文件的全局路径

最后再用 update
方法主动更新一下全局的配置就可以啦。
vscode.window .showInformationMessage("是否设置翻译文件路径", "是", "否") .then((result) => { if (result === "是") { vscode.window .showOpenDialog({ canSelectFiles: false, // 是否可选文件 canSelectFolders: true, // 是否可选文件夹 canSelectMany: false, // 是否可以选择多个 openLabel: "请选择翻译文件夹", }) .then(function (res) { vscode.workspace .getConfiguration() .update("vscodePluginI18n.i18nPath", res[0].path, true); }); } }); }
end
这次就是这样, 希望与你一起进步。
来自:lulu_up
https://segmentfault.com/a/1190000040773678
最后
欢迎关注「 三分钟学前端 」,回复「 交流 」自动加入前端三分钟进阶群,每日一道编程算法面试题(含解答),助力你成为更优秀的前端开发!
号内回复:
「 网络 」,自动获取三分钟学前端网络篇小书(90+页)
「 JS 」,自动获取三分钟学前端 JS 篇小书(120+页)
「 算法 」,自动获取 github 2.9k+ 的前端算法小书
「 面试 」,自动获取 github 23.2k+ 的前端面试小书
「 简历 」,自动获取程序员系列的 120
套模版
》》面试官也在看的前端面试资料《《
“在看和转发” 就是最大的
- Vue3生命周期Hooks的原理及其与调度器(Scheduler)的关系
- 10 个不错的 CSS 小技巧
- 教你使用 koa2 vite ts vue3 pinia 构建前端 SSR 企业级项目
- 别卷了,快来玩 | React Three.js 实现一个超好玩的3D游戏:美女与龙珠
- 手动实现Vue3 & 原理解析:setup环境 & reactive函数 & effect函数(一)
- 前端代码的三种设计模式
- 觉得自己的页面不够花哨吗,试试clip-path吧
- 简易版 useState 实现
- 回溯算法汇总一
- CSS 的 Filter属性竟然如此好玩
- 轻轻松松拿下 JS 浅拷贝、深拷贝
- 2022 前端应该掌握的 10 个 JS 小技巧
- 一文搞懂 Vue3.0 为什么采用 Proxy
- 字节飞书面试——请实现 Promise.all
- 我把 Vue3 项目中的 Vuex 去除了,改用 Pinia
- 从0到1400star,从阮一峰周刊到尤雨溪推荐,小透明开源项目的2021年总结
- type 和 interface的区别知多少?
- 当webpack有了vite的速度你会喜欢吗?
- 前端面试百问(含解答)
- 很多人上来就删除的package-lock.json,还有这么多你不知道的(深度内容)