写个vscode插件, 帮忙浏览i18n我的项目的代码

介绍

     作者以后参加的我的项目是面向寰球用户的, 我的项目免不了要做国际化解决, 哪怕只是一个简略的ok按钮ok文案都要翻译成不同国家的语言展现, 所以在代码外面往往咱们不能够间接命名为ok, 而是可能命名为user_base_plan_edit_ok_button这类的名字, 并且为了辨别i18n与其它命名, 咱们团队会采纳全大写的形式相似USER_BASE_PLAN_EDIT_OK_BUTTON, 而这样的代码多了之后浏览起来会让眼睛干涩, 相似上面图里的伪代码:

     为了解决这个不好浏览的问题我比拟预期的成果是, 当鼠标悬浮在指标文字身上时会浮现出一个弹框, 而这个弹框至多要通知我这个词语的中文或英文意思, 成果如下:

     能够看出这个插件如果做好了不肯定只能用在i18n这个只是点上, 能够用在很多方面, 比方某个code103993283这个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 办法, 他有四个次要的参数:

  1. canSelectFiles 是否可选文件
  2. canSelectFolders 是否可选文件夹
  3. canSelectMany 是否能够多选
  4. openLabel 提醒文案
  5. 返回值是数组, 第一个元素的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

     这次就是这样, 心愿与你一起提高。