轉換本地化模式
在 Lit Localize 轉換模式中,會為每個語系產生一個獨立的資料夾。每個資料夾都包含該語系中應用程式的完整獨立建置,並移除所有執行階段 @lit/localize
程式碼。
msg
呼叫會被每個語系中字串或範本的靜態本地化版本取代。str
標籤會被移除。@lit/localize
匯入會被移除。- 範本會經過最佳化,盡可能將不必要的表達式摺疊到父範本中,以移除這些表達式。
例如,假設原始碼為
// src/launch-button.js
import {msg} from '@lit/localize';
render() {
return html`<button>${msg('Launch rocket')}</button>`
}
將會產生以下檔案
// locales/en/launch-button.js
render() {
return html`<button>Launch rocket</button>`
}
// locales/es-419/launch-button.js
render() {
return html`<button>Lanza cohete</button>`
}
設定轉換模式
“設定轉換模式” 的永久連結在您的 lit-localize.json
設定中,將 mode
屬性設定為 transform
,並將 output.outputDir
屬性設定為您希望產生本地化應用程式資料夾的位置。請參閱轉換模式設定以取得更多詳細資訊。
在您的 JavaScript 或 TypeScript 專案中,您可以選擇性呼叫 configureTransformLocalization
,並傳遞具有以下屬性的物件:
sourceLocale: string
:撰寫原始範本所使用的語系。指定為語系代碼 (例如:"en"
)。
configureTransformLocalization
會傳回具有以下屬性的物件:
getLocale
:傳回作用中語系代碼的函數。
例如
import {configureTransformLocalization} from '@lit/localize';
export const {getLocale} = configureTransformLocalization({
sourceLocale: 'en',
});
設定初始語系
“設定初始語系” 的永久連結在轉換模式中,作用中語系是由您載入的 JavaScript 套件決定。您如何決定在頁面載入時要載入哪個套件取決於您。
例如,如果應用程式的語系反映在 URL 路徑中,您可以在 HTML 檔案中加入一個內嵌指令碼,該指令碼會檢查 URL 並插入適當的 <script>
標籤
在動態選擇指令碼名稱時,請務必驗證您的語系代碼。以下範例是安全的,因為只有在指令碼符合我們已知的其中一個語系代碼時,才能載入指令碼,但如果我們的比對邏輯不夠精確,可能會導致錯誤或注入不安全的 JavaScript 的攻擊。
import {allLocales} from './generated/locales.js';
const url = new URL(window.location.href);
const unsafeLocale = url.searchParams.get('locale');
const locale = allLocales.includes(unsafeLocale) ? unsafeLocale : 'en';
const script = document.createElement('script');
script.type = 'module';
script.src = `/${locale}.js`;
document.head.appendChild(script);
為了獲得更好的效能,您可以在伺服器上將適當的指令碼標籤靜態地渲染到您的 HTML 檔案中。這樣可以讓瀏覽器盡快開始下載您的指令碼。
切換語系
“切換語系” 的永久連結在轉換模式中,setLocale
函數不可用。請改為重新載入頁面,以便下次載入時選取不同的語系套件。
例如,這個 locale-picker
自訂元素會在從下拉式清單中選取新的語系時載入新的 URL
import {LitElement, html} from 'lit';
import {customElement} from 'lit/decorators.js';
import {getLocale} from './localization.js';
import {allLocales} from './generated/locales.js';
@customElement('locale-picker');
export class LocalePicker extends LitElement {
render() {
return html`
<select @change=${this.localeChanged}>
${allLocales.map(
(locale) =>
html`<option value=${locale} selected=${locale === getLocale()}>
${locale}
</option>`
)}
</select>
`;
}
localeChanged(event: Event) {
const newLocale = (event.target as HTMLSelectElement).value;
const url = new URL(window.location.href);
if (url.searchParams.get('locale') !== newLocale) {
url.searchParams.set('locale', newLocale);
window.location.assign(url.href);
}
}
}
import {LitElement, html} from 'lit';
import {getLocale} from './localization.js';
import {allLocales} from './generated/locales.js';
export class LocalePicker extends LitElement {
render() {
return html`
<select @change=${this.localeChanged}>
${allLocales.map(
(locale) =>
html`<option value=${locale} selected=${locale === getLocale()}>
${locale}
</option>`
)}
</select>
`;
}
localeChanged(event) {
const newLocale = event.target.value;
const url = new URL(window.location.href);
if (url.searchParams.get('locale') !== newLocale) {
url.searchParams.set('locale', newLocale);
window.location.assign(url.href);
}
}
}
customElements.define('locale-picker', LocalePicker);
Rollup 整合
“Rollup 整合” 的永久連結如果您使用 Rollup,並且希望使用整合解決方案,而不是單獨執行 lit-localize build
命令,請從 @lit/localize-tools/lib/rollup.js
將 localeTransformers
函數匯入您的 Rollup 設定。
此函數會產生 {locale, transformer}
物件的陣列,您可以使用這些物件搭配 transformers 選項,也就是 @rollup/plugin-typescript 的選項,為每個語系產生一個單獨的套件。
如果您撰寫 JavaScript,請不用擔心在此處看到使用的 TypeScript 編譯器。Lit Localize 依賴 TypeScript 編譯器來剖析、分析和轉換您的原始碼,但它也處理純 JavaScript 檔案!
以下 rollup.config.mjs
會為您的每個語系在 ./bundled/<locale>/
目錄中產生一個縮小的套件
import typescript from '@rollup/plugin-typescript';
import {localeTransformers} from '@lit/localize-tools/lib/rollup.js';
import resolve from '@rollup/plugin-node-resolve';
import {terser} from 'rollup-plugin-terser';
// Config is read from ./lit-localize.json by default.
// Pass a path to read config from another location.
const locales = localeTransformers();
export default locales.map(({locale, localeTransformer}) => ({
input: `src/index.ts`,
plugins: [
typescript({
transformers: {
before: [localeTransformer],
},
}),
resolve(),
terser(),
],
output: {
file: `bundled/${locale}/index.js`,
format: 'es',
},
}));
import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import {terser} from 'rollup-plugin-terser';
import summary from 'rollup-plugin-summary';
import {localeTransformers} from '@lit/localize-tools/lib/rollup.js';
// Config is read from ./lit-localize.json by default.
// Pass a path to read config from another location.
const locales = localeTransformers();
export default locales.map(({locale, localeTransformer}) => ({
input: `src/index.js`,
plugins: [
typescript({
transformers: {
before: [localeTransformer],
},
// Specifies the ES version and module format to emit. See
// https://typescript.dev.org.tw/docs/handbook/tsconfig-json.html
tsconfig: 'jsconfig.json',
// Temporary directory where transformed modules will be emitted before
// Rollup bundles them.
outDir: 'bundled/temp',
// @rollup/plugin-typescript always matches only ".ts" files, regardless
// of any settings in our jsconfig.json.
include: ['src/**/*.js'],
}),
resolve(),
terser(),
summary({
showMinifiedSize: false,
}),
],
output: {
file: `bundled/${locale}/index.js`,
format: 'es',
sourcemap: true,
},
}));