寫個(gè)vscode插件, 幫助閱讀i18n項(xiàng)目的代碼
介紹
ok按鈕的ok文案都要翻譯成不同國(guó)家的語言展示, 所以在代碼里面往往我們不可以直接命名為ok, 而是可能命名為user_base_plan_edit_ok_button這類的名字, 并且為了區(qū)分i18n與其它命名, 我們團(tuán)隊(duì)會(huì)采用全大寫的方式類似USER_BASE_PLAN_EDIT_OK_BUTTON, 而這樣的代碼多了之后閱讀起來會(huì)讓眼睛干澀, 類似下面圖里的偽代碼:
不好閱讀的問題我比較預(yù)期的效果是, 當(dāng)鼠標(biāo)懸浮在目標(biāo)文字身上時(shí)會(huì)浮現(xiàn)出一個(gè)彈框, 而這個(gè)彈框至少要告訴我這個(gè)詞語的中文或英文意思, 效果如下:
i18n這個(gè)只是點(diǎn)上, 可以用在很多方面, 比如某個(gè)code103993283這個(gè)code具體代表什么含義可以做個(gè)插件展示出來。一: 初始化vscode項(xiàng)目
記一次前端"vscode插件編寫實(shí)戰(zhàn)"超詳細(xì)的分享會(huì)(建議收藏哦)(上篇)
記一次前端"vscode插件編寫實(shí)戰(zhàn)"超詳細(xì)的分享會(huì)(建議收藏哦)(下篇)
i18n2cyo code
二: 初始化架構(gòu)
extension.js文件我們清理干凈:const vscode = require("vscode");
function activate(context) {
vscode.window.showInformationMessage("i18n翻譯插件加載完成");
}
module.exports = {
activate,
};package.json文件: 設(shè)置當(dāng)資源加載完就開始加載我們的插件{
// ...
"activationEvents": [
"onStartupFinished"
],
// ...
}
f5開啟調(diào)試模式, 出現(xiàn)下圖就證明插件可以正常啟動(dòng)了:
三: 初始化hover文件
hover后的邏輯都放在src里面:
extension.js, 把hover方法加進(jìn)去: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 導(dǎo)出懸停時(shí)的處理方法const vscode = require("vscode");
module.exports = vscode.languages.registerHoverProvider("*", {
provideHover(document, position) {
return new vscode.Hover(`i18n插件前來助你渡劫`);
},
});

四: i18n目標(biāo)文案的識(shí)別
i18n文案都是大寫, 并且使用下劃線相互鏈接, 而我發(fā)現(xiàn)全局除了i18n文案外沒有字符串里超過三個(gè)下劃線, 并且i18n文案至少四個(gè)下劃線, 所以當(dāng)前我使用的是判斷字符串里面是否含有超過三個(gè) '_'。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就是我們獲取到的被懸停的文本五: 如何翻譯成中文
要被翻譯的文案, 這里我們就要研究如何翻譯這個(gè)文案了, 一般針對(duì)i18n都會(huì)有個(gè)翻譯的字典包, 我們團(tuán)隊(duì)的就是一個(gè)json文件, 不同的是每個(gè)key是小寫的, 大致的樣子如下:
要被翻譯的文案轉(zhuǎn)換為小寫, 再去匹配一下就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字典都是放在同一個(gè)文件夾里面的, 所以我只需要知道這個(gè)文件夾即可, 默認(rèn)取出里面的中文與英文文案, 改造一下吧。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當(dāng)然可以由用戶來配置啦, 接下來我們就把它研究。六: setting配置
寫死在插件里面, 很多時(shí)候需要用戶自己來設(shè)置, 這時(shí)我們就需要vscode的setting的概念了, 具體如下圖所示:
第一步: 初始化配置項(xiàng)
package.json文件添加setting配置項(xiàng):{
"contributes": {
"configuration": {
"type": "object",
"title": "i18n翻譯配置",
"properties": {
"vscodePluginI18n.i18nPath": {
"type": "string",
"default": "",
"description": "翻譯文件的位置"
},
"vscodePluginI18n.open": {
"type": "boolean",
"default": true,
"description": "開啟18n翻譯"
}
}
}
},
}
type設(shè)置為布爾會(huì)自動(dòng)生成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"); 寫在最上方, 可能會(huì)導(dǎo)致無法關(guān)閉懸停翻譯效果, 這個(gè)里面有坑我們一會(huì)詳細(xì)說說。第三步: 懸停時(shí)讀取路徑
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()]}
`);
}
}
},
});七: 何時(shí)判斷是否開啟插件
extension.js文件里面引入了hover模塊, 則就算我們判斷了用戶未開啟i18n翻譯流程也會(huì)走到hover模塊, 但是如果我們?cè)谂袛嘤脩羰欠耖_啟i18n翻譯后進(jìn)行引入hover模塊就會(huì)造成, 如果用戶改變配置開始翻譯無法及時(shí)響應(yīng), 需要用戶重啟一下, 所以具體這里如何設(shè)計(jì)需要大家酌情啦。八: 提示彈框
i18n翻譯但是沒配置路徑, 那么我們其實(shí)可以出現(xiàn)一個(gè)彈框提示用戶是否要來填寫這個(gè)翻譯字典的路徑, 類似下圖的效果:
extension.js文件里面使用showInformationMessage這個(gè)方法, 但是要增加兩個(gè)參數(shù):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("是否設(shè)置翻譯文件路徑", "是", "否")
.then((result) => {
if (result === "是") {
}
});
}
}
module.exports = {
activate,
};
九: 選擇文件
vscode.window.showOpenDialog 方法, 他有四個(gè)主要的參數(shù):canSelectFiles是否可選文件canSelectFolders是否可選文件夾canSelectMany是否可以多選openLabel提示文案返回值是數(shù)組, 第一個(gè)元素的path屬性, 就是文件的全局路徑

update方法主動(dòng)更新一下全局的配置就可以啦。vscode.window
.showInformationMessage("是否設(shè)置翻譯文件路徑", "是", "否")
.then((result) => {
if (result === "是") {
vscode.window
.showOpenDialog({
canSelectFiles: false, // 是否可選文件
canSelectFolders: true, // 是否可選文件夾
canSelectMany: false, // 是否可以選擇多個(gè)
openLabel: "請(qǐng)選擇翻譯文件夾",
})
.then(function (res) {
vscode.workspace
.getConfiguration()
.update("vscodePluginI18n.i18nPath", res[0].path, true);
});
}
});
}end

評(píng)論
圖片
表情
