始めに
@satokaz さんが先行して同様の記事を書いてくださってるのですが、 "Keep It Simple, Stupid!" と大きくプリントされた金属バットを贈ってあげなければならないような vscode-nls 及び i18n-sample を元に記述されており残念なことになってるので、 vscode-nls 及び i18n-sample をベースしないシンプルなローカライズ対応方法について Keep It Simple, Stupid!💢💢💢 と叫びながらまとめてみました。
なお、この記事は拡張のコード部分については TypeScript を前提に記述してますので、 JavaScript を利用されている場合は若干適当に読み替えてください。また、テーマやスニペットなどの拡張の場合のローカライズについては試しておらず、その周りの事情は私は把握しておりません。
対応内容まとめ
-
./package.json
内のローカライズしたいテキストの内容を %key% の形に修正 -
./package.nls.json
ファイルを作成し、各 %key% に対する default のテキストを記述 -
./package.nls.
ロケール.json
(./package.nls.en.json
とか./package.nls.ja.json
)なファイルを作成し、そのロケールでの各 %key% に対するテキストを記述 -
./src/extension.ts
内のコードでvscode.env.language
にロケール(en
とかja
といった文字列)が入ってるのでそれを見てテキストを出しわける
簡単にまとめるとと言うかホントにもうこれだけなんですが、一応、以下にもうちょっと詳細に書き記しておきます。
対応可能なロケール
2018年10現在は次のようになっています。
表示言語 | ロケール |
---|---|
English (US) | en |
Simplified Chinese | zh-CN |
Traditional Chinese | zh-TW |
French | fr |
German | de |
Italian | it |
Spanish | es |
Japanese | ja |
Korean | ko |
Russian | ru |
Bulgarian | bg |
Hungarian | hu |
Portuguese (Brazil) | pt-br |
Turkish | tr |
オリジナルの表はこちらにあります。
./package.json
./package.json
にはさまざまな情報が含まれているのですが、2018年10月現在ローカライズ可能なのは
- ✅ コマンドのカテゴリ
- ✅ コマンドのタイトル
- ✅ 設定のタイトル
- ✅ 設定の default 値
- ✅ 設定の description
などであり
- 🚫 拡張の名前
- 🚫 拡張の description
- 🚫 拡張の readme
あたりはローカライズできません。( VS Code 組み込みの拡張は description がローカライズされてたりするのですが、これはランゲージパックを元に本体側が特別に処理しているモノであり、サードパーティー製の拡張ではできないっぽいです。ランゲージパックまで自作すればイケるかもですが・・・ )
ちなみにコマンドや設定まわりもローカライズこそはできるのですが、 VS Code 内での拡張情報表示が対応してくれておらず、 コントリビューション
の情報を確認するとローカライズの為のキーが置換されずにそのまま表示されるという悲しいことになっています。この問題の詳細についてはこちらの 🦋issue を参照してください。
./package.json のローカライズ対応方法
元のローカライズ対応前の ./package.json
の内容の一部がこんな感じだとします。
"title": "Bark",
"category": "Dog",
それを次のように書き換えます。
"title": "%bark-command-title%",
"category": "%dog-category%",
%
で括った文字列がローカライズの為のキーとして使われ、JSONのキーとして利用可能な文字列であれば基本的になんでもいいハズです。( ただ使用する文字は ASCII の範囲内に限定しておいた方が無難だとは思います。 )
次に default のロケールテキストとして ./package.nls.json
ファイルを作成し次のように記述します。
{
"bark-command-title": "Bark",
"dog-category": "Dog"
}
最後に対応したい言語に合わせて ./package.nls.
ロケール.json
なファイル( 日本語対応するなら ./package.nls.ja.json
) を作成し次のように記述します。
{
"bark-command-title": "吠える",
"dog-category": "イヌ"
}
./package.json
のローカライズ対応方法としては以上です。
拡張コード内のテキスト
基本的にはユーザーが Configure Display Language
コマンドで locale.json
内の locale
の値として設定した en
とか ja
といった文字列が vscode.env.language
を見れば入ってるんでそれに合わせて表示するテキストを切り替えてやるだけです。
以上でお終いと言えばお終いなんですが以下に実際に私が採用してる具体的なコードを紹介しておきます。
./src/extension.ts
の最初の方に次のような import 指定と共通コードを記述します。
import localeEn from "../package.nls.json";
import localeJa from "../package.nls.ja.json";
export type LocaleKeyType = keyof typeof localeEn;
interface LocaleEntry
{
[key : string] : string;
}
const localeTableKey = vscode.env.language;
const localeTable = Object.assign(localeEn, ((<{[key : string] : LocaleEntry}>{
ja : localeJa
})[localeTableKey] || { }));
const localeString = (key : string) : string => localeTable[key] || key;
const localeMap = (key : LocaleKeyType) : string => localeString(key);
このコードでは ./package.json
のローカライズ対応用の JSON ファイルを流用且つコード上必要なローカライズのキーとテキストを書き足して利用しています。
JSON をそのまま import して利用する為、必要に応じて ./tsconfig.json
の compilerOptions
のところで
{
"compilerOptions": {
...
"resolveJsonModule": true,
"esModuleInterop": true
},
"exclude": [
...
]
}
のように resolveJsonModule
と esModuleInterop
をともに true
で指定してください。( 前者の指定がないとファイルが見つからないとエラーになり、後者の指定がないと default が export されてないとエラーになります。 )
なお、ここまでの編集を行って本来的には問題が解決してるハズなのに VS Code 上でエラーが出続けてしまうことがありますが、その時は VS Code を再起動すればエラーが消えます。
で、あとは先のコードで定義した localeString()
関数あるいは localeMap()
関数を使って
console.log(localeString("dog-category"));
console.log(localeMap("dog-category"));
のような形で使うだけです。
localeString()
関数はロケール上の対応するテキストが見つからなかった時にキーをそのまま返すようにしてありますので、元の英語版のテキストをそのままキーとして流用すれば ./package.nls.json
への記述が省略できます。また、ロケールのテキストの参照の仕方としてどの言語であろうと最初に ./package.nls.json
の記述とマージしてしまうので、部分的な多言語対応も可能です。( 対応してない箇所は default のテキストが表示されます。 )
localeMap()
関数は引数のチェックがコンパイラによって行われ、 ./package.nls.json
に存在しないキーが指定されるとコンパイルエラーになりますし、 VS Code による入力補完も効きます。
対応サンプル
実際に私が日本語対応を行った拡張で修正箇所がわかりやすいように多言語対応の基礎部分と日本語対応部分を分けてコミットしてるので良ければ参考にしてください。