乐趣区

关于vscode插件:写个vscode插件-帮助阅读i18n项目的代码

写个 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

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

退出移动版