i18n

完整的插件包括 VS Code 插件OpenSumi 插件package.json 贡献点共同组成,针对不同环境及插件不同功能,国际化的实现在兼容 VS Code 插件的同时也具备了一定程度的扩展能力。

VS Code 插件

OpenSumi 兼容了 VS Code 官方提供的一些语言包插件(建议使用 2.23.6 以上的 OpenSumi 版本),如:

当前仅支持 zh-cnen-us 两种语言的切换能力,如有进一步需求,可到 issues 提交适配需求。

VS Code 插件在 1.74 版本后废弃了原有的 i18n 方案,推荐在插件中采用新的 l10n 做为替代方案,如遇到无法正常被国际化的文本,可检查插件版本,考虑使用旧一点的插件版本。

当前 OpenSumi 暂未支持通过 vscode.l10n 实现的本地化能力插件,如遇到相关问题,可以在 #2341 留言或 +1,我们会进一步加快适配进度。

PackageJSON 中声明

在插件 package.json 中支持部分 Menu、Command 等纯静态的贡献点,这些贡献点中的文案可以通过使用 %{section}% 的占位符来声明国际化文案的字段,例如注册一个命令:

{
  "contributes": {
    "commands": [
      {
        "command": "Hello OpenSumi",
        "title": "%test-extension-hello-command%"
      }
    ]
  },
}

在插件中新增一个名为 package.nls.json 的文件作为默认英文语言包

{
  "test-extension-hello-command": "Test i18n for command"
}

对于中文则需要写在 package.nls.zh-cn.json 中,如:

{
  "test-extension-hello-command": "测试一下命令国际化"
}

同理对于插件贡献的任何可以显示文案在 IDE 界面中的贡献点,都可以通过这种方式注册语言包,例如 configurations 中可以这样使用:

{
  ...
  "configuration": {
    "title": "%test-extension-config-title%",
    "properties": {
      "my-extension.enable-auto-bugfix-feature": {
        "type": "boolean",
        "default": false,
        "description": "%test-extension-config.config.enable-feature%"
      }
    }
  }
  ...
}

该插件贡献点会注册一份配置项到框架设置页,同样在 package.nls.jsonpackage.nls.zh-cn.json 中声明

{
  "test-extension-config-title": "测试插件配置",
  "test-extension-config.config.enable-feature": "测试开启功能"
}

效果如下:

configurations

Node 层使用

参考 VS Code i18n Sample,需要在将国际化语言包按照 i18n/{language} 的结构编写在插件中。若你的插件源码文件 src/utils.ts 需要国际化支持,则应该把语言文案编写在 i18n/out/utils.i18n.json 中,编写 OpenSumi 插件 Node 端代码同理。

以上示例适用于使用 gulpfile.js 构建的纯 VS Code 插件, 部分新版本插件可能不适用。

对于使用 OpenSumi CLI 初始化的插件项目,使用时需要先在插件中安装最新版本 vscode-nls, 示例代码如下:

// 插件入口 extension.ts 或 extend/node/index.ts 中
import * as nls from 'vscode-nls';
import * as vscode from 'vscode';

const localize = nls.config({
  messageFormat: nls.MessageFormat.bundle,
  bundleFormat: nls.BundleFormat.standalone
})();

function activate() {
  vscode.window.shoeInfomationMessage(localize('i18n.key', 'defaulMessage'));
}

// 其他文件
import * as nls from 'vscode-nls';

const localize = nls.loadMessageBundle();

//...

与 VS Code 实例中不同的是,nls.config 的参数存在部分写法上的区别:

// 使用 gulp + tsc 时
const localize = nls.config({ messageFormat: nls.MessageFormat.file });

// 使用 OpenSumi CLI / webpack 时
const localize = nls.config({
  messageFormat: nls.MessageFormat.bundle,
  bundleFormat: nls.BundleFormat.standalone
})();

不同的参数对应了 vscode-nls 这个模块在运行时将以何种方式加载语言包文件。

  • 若是纯 VS Code 插件,使用 gulp + tsc 构建插件,则运行时会通过 i18n 目录结构加载对应文件的语言包,构建时只会生成 nls.metadata.jsonnls.metadata.header.json 用于记录对应的语言文件。
  • 若是 OpenSumi 插件 Node 端,或使用 Webpack 打包的 VS Code 插件,将插件压缩为一个单文件,则运行时会尝试加载 i18n 目录下的 nls.bundle.{language}.json 文件。

同时根据 VS Code 插件示例,若 i18n 对应语言目录下包含 package.nls.json 时(如 i18n/zh-cn/package.nls.json),使用 sumi compile/watch 命令时也会被提取到插件根目录下并重命名为 package.nls.{language}.json

无论是 VS Code 插件还是 OpenSumi 插件,在运行 sumi compilesumi watch 时都会同时将对应语言的提取到 out/ 目录下。

WEBPACK Hash: 1da8c87af3944336632a
Version: webpack 4.44.1
Time: 1197ms
Built at: 2020-08-10 20:52:32
                   Asset       Size  Chunks             Chunk Names
                index.js   7.86 KiB       0  [emitted]  index
     nls.bundle.jpn.json   24 bytes          [emitted]  // 提取出的日文语言包
         nls.bundle.json   52 bytes          [emitted]  // 默认语言包(英文)
   nls.bundle.zh-cn.json   37 bytes          [emitted]  // 中文语言包
nls.metadata.header.json  149 bytes          [emitted]  // 元数据
       nls.metadata.json  118 bytes          [emitted]  // 元数据
WEBPACK Compiled successfully in 1.2s!

Browser 层使用

在 Browser 层同样可以将文案声明在 package.nls.json 中,但在使用时需要从 sumi-browser 模块导入 localize 方法,第一个参数表示文案 id ,即声明在 package.nls.json 中的字段名,第二个参数为找不到对应语言包文案时的默认值。

import { localize } from 'sumi-browser';

export const MyPanel = () => {
  return <div>{localize('test-extension-view-title', '测试插件标题')}</div>;
};

对应的,在 package.nls.json 中的定义如下:

{
  "test-extension-view-title": "Test Title"
}

参考示例

OpenSumi Extension Sample - i18n