前言
目前正在开发基于VSCode实现的公司内部编辑器,记录自定义修改了的模块开发流程。如果对某些功能实现看不懂或者想实现某些功能但是没头绪,可以评论区提问交流。
效果展示

在已安装插件列表中不存在翻译插件、命令面板中可切换中英文,说明这是内置的中文翻译插件,用户无法卸载。并且在自定义的主窗体中可以响应切换的中英文。
实现流程
添加内置插件
- 下载主程序版本对应的翻译插件vsix文件
- 先在
VSCode插件市场中找到中文翻译包的历史版本,对应你所自定义的开源Code版本。

- 如果可以直接下载成功,则不需要这一步。获取到版本号后,在浏览器中替换此链接版本号下载插件文件
https://ms-ceintl.gallery.vsassets.io/_apis/public/gallery/publisher/MS-CEINTL/extension/vscode-language-pack-zh-hans/1.104.2025091009/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage,并把下载后文件名字改为ms-ceintl.vscode-language-pack-zh-hans.vsix。 - 把下载好的插件放置到
code项目的extensions-vsix目录下
- 在
product.json中添加内置翻译插件配置, sha256如果与我同版本则可以复用,如果不同版本,则在打包报错时改为使用报错输出给的sha256值。
json
{
"builtInExtensions": [
{
"name": "ms-ceintl.vscode-language-pack-zh-hans",
"version": "1.104.2025081708",
"sha256": "2015e764d028adb155bbaf143b0686c9504dc8f4c82d8804641cba93f1143630",
"repo": "https://github.com/Microsoft/vscode-loc",
"vsix": "./extensions-vsix/ms-ceintl.vscode-language-pack-zh-hans.vsix",
"metadata": {
"id": "ms-ceintl.vscode-language-pack-zh-hans",
"publisherId": {
"publisherId": "ms-ceintl",
"publisherName": "ms-ceintl",
"displayName": "Microsoft",
"flags": "verified"
},
"publisherDisplayName": "Microsoft"
}
}
]
}
问题与排查
- 此时直接打包并运行程序,会发现程序支持了命令面板中切换中英文,但是切换重启程序后并没有使用到中文的翻译;查看命令面板发现也是未切换。

- 问题是出在了
插件安装和语言包加载流程中,内置的插件是不走安装流程的,也就导致了无法写入到languagePacks.json配置中,启动项目时也就无法加载到翻译文件
解决问题思路
- 既然内置插件不走插件安装流程,且又需要确保翻译插件的数据添加到
languagePacks.json文件中;那我们就干脆在启动时主动执行一次添加packs的操作。 - 由于是二次开发已有项目,那么就要尽量减少改动,遵循原程序的开发流程。所以我的实现方式是复用已有的方法,并且在app加载完
services后再实现。以下是代码实现:
js
// 检测内置语言插件是否加载成功
private async checkLangBuiltinExtensions(instantiationService: IInstantiationService) {
const userLocale = process.env['jerry_lang_reload']
if (userLocale) {
// const extensionsScannerService = accessor.get(IExtensionsScannerService);
// const extensionManagementService = accessor.get(IExtensionManagementService);
const productService = instantiationService.invokeFunction(accessor => accessor.get(IProductService));
const userDataProfileService = instantiationService.invokeFunction(accessor => accessor.get(IUserDataProfilesMainService));
const extensionScanner = instantiationService.createInstance(ExtensionsScanner, () => Promise.resolve());
const packCache = instantiationService.createInstance(LanguagePacksCache);
const packs = await packCache.getLanguagePacks()
if (!packs[userLocale]) {
const exts = await extensionScanner.scanExtensions(null, userDataProfileService.defaultProfile.extensionsResource, { version: productService.version, date: productService.date })
// const langPacks = await packCache.update(exts)
const packs2 = await packCache.update(exts)
// console.log({ packs, exts, packs2 });
this.logService.debug('checkLangBuiltinExtensions:', userLocale, Object.keys(packs2));
this.lifecycleMainService.relaunch()
}
}
}
用到的env['jerry_lang-reload']后面会讲解从何而来,此时要记得去导出ExtensionsScanner类;
4. 开始优化实现
- 在
src/main.ts中优化默认使用语言
- 在解析nls配置时,标记环境变量判断是否需要走检测插件流程

总结
到此处,应该功能是已经正常实现了,可以打包之后测试一下。有其他模块想要自定义的可以说一下。