本地化
本地化是在您的應用程式和元件中支援多種語言和地區的過程。Lit 透過 @lit/localize
函式庫提供第一方本地化支援,相較於第三方本地化函式庫,它有許多優勢,使其成為一個不錯的選擇
原生支援本地化模板內的表達式和 HTML 標記。無需新的語法和變數替換的插值執行階段——只需使用您已有的模板即可。
當地區切換時,自動重新渲染 Lit 元件。
僅 1.27 KiB(縮小 + 壓縮)的額外 JavaScript。
可選擇為每個地區編譯,將額外 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 標記時,您應該偏好使用 str
而不是 html
,因為它的效能開銷稍微較少。如果您忘記在帶有表達式的字串上使用 html
或 str
標記,則在您執行 lit-localize
命令時會引發錯誤。
不正確
import {msg} from '@lit/localize';
msg(`Hello ${name}`);
正確
import {msg, str} from '@lit/localize';
msg(str`Hello ${name}`);
在這些情況下需要 str
標記,因為未標記的模板字串文字會在被 msg
函式接收之前評估為常規字串,這表示動態表達式值可能無法被擷取並替換為字串的本地化版本。
地區代碼
“地區代碼”的永久連結地區代碼是用於識別人類語言的字串,有時還包括地區、腳本或其他變體。
Lit Localize 不強制使用任何特定的地區代碼系統,但強烈建議使用 BCP 47 語言標籤標準。BCP 47 語言標籤的一些範例為
- en:英文
- es-419:拉丁美洲使用的西班牙文
- zh-Hans:以簡體字書寫的中文
Lit Localize 定義了一些用於指稱地區代碼的術語。這些術語會用於此文件、Lit Localize 設定檔和 Lit Localize API 中
- 來源地區
用於在您的原始程式碼中編寫字串和模板的地區。
- 目標地區
您的字串和模板可以翻譯成的地區。
- 活動地區
目前正在顯示的全域地區。
輸出模式
“輸出模式”的永久連結Lit Localize 支援兩種輸出模式
執行階段模式使用 Lit Localize 的 API 在執行階段載入本地化訊息。
轉換模式藉由為每個地區建立單獨的 JavaScript 套件來消除 Lit Localize 執行階段程式碼。
不確定要使用哪種模式?從執行階段模式開始。由於核心 msg
API 是相同的,因此稍後切換模式很容易。
執行階段模式
“執行階段模式”的永久連結在執行階段模式中,會為您的每個地區產生一個 JavaScript 或 TypeScript 模組。每個模組都包含該地區的本地化模板。當活動地區切換時,會匯入該地區的模組,並且所有本地化元件都會重新渲染。
執行階段模式可讓地區切換非常快速,因為不需要重新載入頁面。但是,與轉換模式相比,渲染效能會略有成本。
產生的輸出範例
“產生的輸出範例”的永久連結// locales/es-419.ts
export const templates = {
hf71d669027554f48: html`Hola <b>Mundo</b>`,
};
有關執行階段模式的完整詳細資訊,請參閱執行階段模式頁面。
轉換模式
“轉換模式”的永久連結在轉換模式中,會為每個地區產生一個單獨的資料夾。每個資料夾都包含該地區中您應用程式的完整獨立版本,其中 msg
包裝函式和所有其他 Lit Localize 執行階段程式碼已完全移除。
轉換模式需要 0 KiB 的額外 JavaScript,並且渲染速度非常快。但是,切換地區需要重新載入頁面,才能載入新的 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,使用字串的雜湊值。
如果兩個 msg
呼叫共享相同的 ID,則它們會被視為相同的訊息,這表示它們將被翻譯為單一單位,並且相同的翻譯將在兩個地方被替換。
例如,這兩個 msg
呼叫位於兩個不同的檔案中,但由於它們具有相同的內容,因此它們將被視為一個訊息。
// 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”的永久連結訊息 ID 可以透過指定 msg
函式的 id
選項來覆寫。在某些情況下,這可能是必要的,例如當相同的字串有多個含義時,因為每種含義在另一種語言中可能會以不同的方式編寫。
msg('Buffalo', {id: 'buffalo-animal-singular'});
msg('Buffalo', {id: 'buffalo-animal-plural'});
msg('Buffalo', {id: 'buffalo-city'});
msg('Buffalo', {id: 'buffalo-verb'});