ローカリゼーション
ローカリゼーションとは、アプリやコンポーネントで複数の言語と地域をサポートするプロセスです。Litは、@lit/localize
ライブラリを通じてローカリゼーションをネイティブサポートしており、サードパーティのローカリゼーションライブラリに比べて多くの利点があります。
ローカライズされたテンプレート内での式とHTMLマークアップのネイティブサポート。変数の置換に新しい構文と補間ランタイムは必要ありません。既存のテンプレートを使用できます。
ロケールが切り替わったときのLitコンポーネントの自動再レンダリング。
追加のJavaScriptはわずか1.27 KiB(縮小+圧縮)です。
オプションで各ロケールにコンパイルすることで、追加のJavaScriptを0 KiBに削減できます。
インストール
「インストール」へのパーマリンク@lit/localize
クライアントライブラリと@lit/localize-tools
コマンドラインインターフェースをインストールします。
npm i @lit/localize
npm i -D @lit/localize-tools
クイックスタート
「クイックスタート」へのパーマリンク- 文字列またはテンプレートを
msg
関数でラップします(詳細)。 lit-localize.json
設定ファイルを作成します(詳細)。lit-localize extract
を実行してXLIFFファイルを作成します(詳細)。- 生成されたXLIFFファイルに
<target>
翻訳タグを追加します(詳細)。 lit-localize build
を実行して、文字列とテンプレートのローカライズされたバージョンを出力します(詳細)。
文字列とテンプレートのローカライズ化
「文字列とテンプレートのローカライズ化」へのパーマリンク文字列またはLitテンプレートをローカライズするには、msg
関数でラップします。msg
関数は、現在アクティブなロケールで指定された文字列またはテンプレートのバージョンを返します。
翻訳が利用可能になる前は、msg
は元の文字列またはテンプレートを返すだけなので、ローカライズの準備ができていない場合でも安全に使用できます。
import {html, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import {msg} from '@lit/localize';
@customElement('my-greeter')
class MyGreeter extends LitElement {
@property()
who = 'World';
render() {
return msg(html`Hello <b>${this.who}</b>`);
}
}
import {html, LitElement} from 'lit';
import {msg} from '@lit/localize';
class MyGreeter extends LitElement {
static properties = {
who: {},
};
constructor() {
super();
this.who = 'World';
}
render() {
return msg(html`Hello <b>${this.who}</b>`);
}
}
customElements.define('my-greeter', MyGreeter);
メッセージの種類
「メッセージの種類」へのパーマリンク通常Litでレンダリングする文字列やテンプレートは、動的な式やHTMLマークアップを含むものを含め、ローカライズできます。
プレーンな文字列
msg('Hello World');
式を含むプレーンな文字列(str
の詳細については式を含む文字列を参照)
msg(str`Hello ${name}`);
HTMLテンプレート
msg(html`Hello <b>World</b>`);
式を含むHTMLテンプレート
msg(html`Hello <b>${name}</b>`);
ローカライズされたメッセージは、HTMLテンプレート内にネストすることもできます
html`<button>${msg('Hello World')}</button>`;
式を含む文字列
「式を含む文字列」へのパーマリンク式を含む文字列は、ローカライズ可能にするために、html
またはstr
でタグ付けする必要があります。文字列にHTMLマークアップが含まれていない場合は、html
よりもstr
を優先する必要があります。パフォーマンスのオーバーヘッドがわずかに少なくなります。式を含む文字列にhtml
またはstr
タグを付け忘れた場合、lit-localize
コマンドを実行するとエラーが発生します。
正しくない
import {msg} from '@lit/localize';
msg(`Hello ${name}`);
正しい
import {msg, str} from '@lit/localize';
msg(str`Hello ${name}`);
タグ付けされていないテンプレート文字列リテラルは、msg
関数によって受信される前に通常の文字列として評価されるため、これらの場合、str
タグが必要です。つまり、動的な式の値をキャプチャして、文字列のローカライズされたバージョンに代入することはできません。
ロケールコード
「ロケールコード」へのパーマリンクロケールコードとは、人間の言語を識別する文字列であり、地域、スクリプト、またはその他のバリエーションを含むこともあります。
Lit Localizeは、特定のロケールコードシステムの使用を義務付けていませんが、BCP 47言語タグ標準を使用することを強くお勧めします。BCP 47言語タグの例をいくつか示します。
- en: 英語
- es-419: ラテンアメリカで話されるスペイン語
- zh-Hans: 簡体字で書かれた中国語
Lit Localizeは、ロケールコードを参照するいくつかの用語を定義しています。これらの用語は、このドキュメント、Lit Localize設定ファイル、およびLit Localize APIで使用されます。
- ソースロケール
ソースコードで文字列とテンプレートを作成するために使用されるロケール。
- ターゲットロケール
文字列とテンプレートを翻訳できるロケール。
- アクティブなロケール
現在表示されているグローバルロケール。
出力モード
「出力モード」へのパーマリンクLit Localizeは、2つの出力モードをサポートしています。
ランタイムモードは、Lit LocalizeのAPIを使用して、ランタイム時にローカライズされたメッセージを読み込みます。
トランスフォームモードは、各ロケールごとに個別のJavaScriptバンドルを構築することで、Lit Localizeランタイムコードを排除します。
どのモードを使用するか不明な場合? ランタイムモードから始めましょう。コアmsg
APIは同じなので、後でモードを切り替えるのは簡単です。
ランタイムモード
「ランタイムモード」へのパーマリンクランタイムモードでは、各ロケールごとに1つのJavaScriptまたはTypeScriptモジュールが生成されます。各モジュールには、そのロケールのローカライズされたテンプレートが含まれています。アクティブなロケールが切り替わると、そのロケールのモジュールがインポートされ、すべてのローカライズされたコンポーネントが再レンダリングされます。
ランタイムモードでは、ページの再読み込みは必要ないため、ロケールの切り替えが非常に高速になります。ただし、トランスフォームモードと比較して、レンダリングパフォーマンスにわずかなパフォーマンスコストがあります。
生成された出力例
「生成された出力例」へのパーマリンク// locales/es-419.ts
export const templates = {
hf71d669027554f48: html`Hola <b>Mundo</b>`,
};
ランタイムモードの詳細については、ランタイムモードページを参照してください。
トランスフォームモード
「トランスフォームモード」へのパーマリンクトランスフォームモードでは、各ロケールごとに個別のフォルダーが生成されます。各フォルダーには、そのロケールでのアプリケーションの完全なスタンドアロンビルドが含まれており、msg
ラッパーとその他のすべてのLit Localizeランタイムコードは完全に削除されています。
トランスフォームモードでは、追加のJavaScriptは0 KiBで、レンダリングが非常に高速です。ただし、ロケールを切り替えるには、新しいJavaScriptバンドルを読み込むためにページを再読み込みする必要があります。
生成された出力例
「生成された出力例」へのパーマリンク// locales/en/my-element.js
render() {
return html`Hello <b>World</b>`;
}
// locales/es-419/my-element.js
render() {
return html`Hola <b>Mundo</b>`;
}
トランスフォームモードの詳細については、トランスフォームモードページを参照してください。
ランタイムモード | トランスフォームモード | |
---|---|---|
出力 | 各ターゲットロケールごとに動的に読み込まれるモジュール。 | 各ロケールごとにスタンドアロンのアプリビルド。 |
ロケールの切り替え | setLocale() を呼び出す | ページを再読み込みする |
JSバイト | 1.27 KiB(縮小+圧縮) | 0 KiB |
テンプレートのローカライズ化 | msg() | msg() |
設定 | configureLocalization() | configureTransformLocalization() |
利点 |
|
|
設定ファイル
「設定ファイル」へのパーマリンクlit-localize
コマンドラインツールは、現在のディレクトリにあるlit-localize.json
という設定ファイルを探します。クイックスタートのために以下の例をコピーアンドペーストし、すべてのオプションの完全なリファレンスについてはCLIと設定ページを参照してください。
JavaScriptを書いている場合は、inputFiles
プロパティに.js
ソースファイルの場所を設定します。TypeScriptを書いている場合は、tsConfig
プロパティにtsconfig.json
ファイルの場所を設定し、inputFiles
を空のままにします。
{
"$schema": "https://raw.githubusercontent.com/lit/lit/main/packages/localize-tools/config.schema.json",
"sourceLocale": "en",
"targetLocales": ["es-419", "zh-Hans"],
"tsConfig": "./tsconfig.json",
"output": {
"mode": "runtime",
"outputDir": "./src/generated/locales",
"localeCodesModule": "./src/generated/locale-codes.ts"
},
"interchange": {
"format": "xliff",
"xliffDir": "./xliff/"
}
}
{
"$schema": "https://raw.githubusercontent.com/lit/lit/main/packages/localize-tools/config.schema.json",
"sourceLocale": "en",
"targetLocales": ["es-419", "zh-Hans"],
"inputFiles": [
"src/**/*.js"
],
"output": {
"mode": "runtime",
"outputDir": "./src/generated/locales",
"localeCodesModule": "./src/generated/locale-codes.js"
},
"interchange": {
"format": "xliff",
"xliffDir": "./xliff/"
}
}
メッセージの抽出
「メッセージの抽出」へのパーマリンクlit-localize extract
を実行して、各ターゲットロケールごとにXLIFFファイルを作成します。XLIFFは、ほとんどのローカリゼーションツールとサービスでサポートされているXML形式です。XLIFFファイルは、interchange.xliffDir
設定オプションで指定されたディレクトリに書き込まれます。
lit-localize extract
たとえば、次のソースがあるとします。
msg('Hello World');
msg(str`Hello ${name}`);
msg(html`Hello <b>World</b>`);
その後、各ターゲットロケールごとに<xliffDir>/<locale>.xlf
ファイルが生成されます。
<!-- xliff/es-419.xlf -->
<trans-unit id="s3d58dee72d4e0c27">
<source>Hello World</source>
</trans-unit>
<trans-unit id="saed7d3734ce7f09d">
<source>Hello <x equiv-text="${name}"/></source>
</trans-unit>
<trans-unit id="hf71d669027554f48">
<source>Hello <x equiv-text="<b>"/>World<x equiv-text="</b>"/></source>
</trans-unit>
XLIFFによる翻訳
「XLIFFによる翻訳」へのパーマリンクXLIFFファイルは手動で編集できますが、通常はサードパーティの翻訳サービスに送信され、専門ツールを使用して言語の専門家によって編集されます。
選択した翻訳サービスにXLIFFファイルをアップロードすると、最終的に新しいXLIFFファイルが返されます。新しいXLIFFファイルはアップロードしたファイルとまったく同じように見えますが、各<trans-unit>
内に<target>
タグが挿入されています。
新しい翻訳XLIFFファイルを受け取ったら、設定済みのinterchange.xliffDir
ディレクトリに保存し、元のバージョンを上書きしてください。
<!-- xliff/es-419.xlf -->
<trans-unit id="s3d58dee72d4e0c27">
<source>Hello World</source>
<target>Hola Mundo</target>
</trans-unit>
<trans-unit id="saed7d3734ce7f09d">
<source>Hello <x equiv-text="${name}"/></source>
<target>Hola <x equiv-text="${name}"/></target>
</trans-unit>
<trans-unit id="hf71d669027554f48">
<source>Hello <x equiv-text="<b>"/>World<x equiv-text="</b>"/></source>
<target>Hola <x equiv-text="<b>"/>Mundo<x equiv-text="</b>"/></target>
</trans-unit>
ローカライズされたテンプレートの構築
「ローカライズされたテンプレートの構築」へのパーマリンクlit-localize build
コマンドを使用して、翻訳をアプリケーションに統合します。このコマンドの動作は、設定されている出力モードによって異なります。
lit-localize build
各モードでの構築方法の詳細については、ランタイムモードとトランスフォームモードのページを参照してください。
メッセージの説明
「メッセージの説明」へのパーマリンクmsg
関数のdesc
オプションを使用して、文字列とテンプレートに人間が読める説明を提供します。これらの説明は、ほとんどの翻訳ツールによって翻訳者に表示され、メッセージの意味を説明し、文脈を付けるために強く推奨されます。
render() {
return html`<button>
${msg("Launch", {
desc: "Button that begins rocket launch sequence.",
})}
</button>`;
}
説明は、XLIFFファイルでは<note>
要素を使用して表されます。
<trans-unit id="s512957aa09384646">
<source>Launch</source>
<note from="lit-localize">Button that begins rocket launch sequence.</note>
</trans-unit>
メッセージID
「メッセージID」へのパーマリンクLit Localizeは、文字列のハッシュを使用して、各msg
呼び出しのIDを自動的に生成します。
2つのmsg
呼び出しが同じIDを共有する場合、それらは同じメッセージとして扱われます。つまり、単一の単位として翻訳され、両方の場所に同じ翻訳が代入されます。
たとえば、これらの2つのmsg
呼び出しは異なるファイルにありますが、内容が同じであるため、1つのメッセージとして扱われます。
// file1.js
msg('Hello World');
// file2.js
msg('Hello World');
IDの生成
「ID生成」へのパーマリンク次の内容は、ID生成に影響します。
- 文字列の内容
- HTMLマークアップ
- 式の位置
- 文字列が
html
でタグ付けされているかどうか
次の内容は、ID生成に**影響しません**
- 式内のコード
- 式の計算された値
- ファイルの場所
たとえば、これらのメッセージはすべて同じIDを共有します。
msg(html`Hello <b>${name}</b>`);
msg(html`Hello <b>${this.name}</b>`);
しかし、このメッセージは異なるIDを持っています。
msg(html`Hello <i>${name}</i>`);
注意:説明を提供してもID生成には影響しませんが、IDは同じで説明が異なる複数のメッセージがあると、抽出された翻訳単位のあいまいさを避けるため、分析中にエラーが発生します。以下は**無効**とみなされます。
msg(html`Hello <b>${name}</b>`);
msg(html`Hello <b>${name}</b>`, {desc: 'A friendly greeting'});
同じIDを持つすべてのメッセージは、同じ説明も持っているようにしてください。
IDの上書き
「IDの上書き」へのパーマリンクmsg
関数のid
オプションを指定することで、メッセージIDを上書きできます。同一の文字列に複数の意味がある場合など、場合によってはこれが必要になることがあります。これは、別の言語ではそれぞれ異なる書き方になる可能性があるためです。
msg('Buffalo', {id: 'buffalo-animal-singular'});
msg('Buffalo', {id: 'buffalo-animal-plural'});
msg('Buffalo', {id: 'buffalo-city'});
msg('Buffalo', {id: 'buffalo-verb'});