必须使用vscode-nls库并调用localize()加载翻译,硬编码字符串无法被VS Code语言机制识别和替换,导致界面无法本地化且补救成本高。

VSCode插件的多语言支持必须用 vscode-nls,硬编码字符串直接导致部分界面无法翻译,且后续补救成本高。
为什么不能在代码里写死提示文字
用户看到的命令标题、错误提示、QuickPick选项等,一旦写成 "Select language" 这类字符串,就脱离了 VS Code 的语言协商机制。VS Code 启动时根据 locale 设置(如 zh-cn)加载对应 package.nls.*.json,但只认通过 localize() 调用的键值——硬编码内容不会被扫描、不会被替换、也不会出现在构建后的语言包里。
- 常见错误现象:
command.hello键在package.nls.zh-cn.json里有翻译,但界面上仍显示英文,说明调用处没走localize() - 调试方法:临时把
locale设为zh-cn并重启,观察哪些文本没变,就是漏掉localize()的地方 - 性能影响:
localize()是轻量同步调用,无运行时开销;而硬编码+手动条件判断语言反而增加分支和维护负担
如何正确组织和加载语言文件
语言资源必须放在项目根目录,命名严格遵循 ISO 639-1 标准,且 package.nls.json 是默认后备(fallback),不是可选。
- 必需文件:
package.nls.json(英文)、package.nls.zh-cn.json、package.nls.ja.json等 - 构建时要确保这些文件被复制进
out/或最终插件包中;用 webpack 的话需加CopyPlugin或配置assets规则 - 初始化位置必须在
activate()最早阶段,否则localize()返回undefined或原始键名 - 示例初始化:
import * as nls from 'vscode-nls';<br>const localize = nls.loadMessageBundle();
localize() 的参数陷阱和动态文本处理
localize() 第一个参数是唯一键(建议带命名空间前缀),第二个是默认值——它不是“备用文案”,而是构建时提取元数据的依据,必须与源码一致。
- 错误写法:
localize('err.timeout', 'Request timeout')和localize('err.timeout', '请求超时')混用,会导致提取工具无法合并键 - 动态参数必须用
{0}、{1}占位,不能拼接:localize('msg.file', 'File {0} not found', fileName) - 复数/性别等复杂场景需用 ICU 格式,例如:
localize('msg.items', '{0, plural, =0{No items} =1{One item} other{# items}}', count) - 键名变更后,所有语言文件都要同步更新,否则缺失键会回退到默认值(即第二个参数),而不是报错
测试和发布前必须验证的三件事
本地开发时容易忽略环境差异,真正生效依赖 VS Code 运行时加载逻辑,不是编译时检查能覆盖的。
- 改完语言文件后,务必清空
~/.vscode/extensions/your-publisher.your-extension-*目录再重装插件,避免缓存旧 bundle - 在设置里手动改
locale(如设为zh-cn),不要只靠系统语言自动继承,有些系统 locale 值不标准(如zh_CN少连字符) - 发布前用
vsce package --no-yarn打包,解压 .vsix 查看是否包含全部nls.*.json文件——漏掉任一语言文件,该语言用户就会看到键名本身
最容易被忽略的是 fallback 行为:当某个键在目标语言文件里缺失时,localize() 不会报错或警告,而是静默返回你传的默认值。这意味着翻译遗漏在测试阶段几乎不可见,只能靠人工核对或借助 vscode-i18n-linter 这类扩展主动扫描缺失项。


















