转换本地化模式
在 Lit Localize 转换模式下,为每个语言区域生成一个单独的文件夹。每个文件夹包含该语言区域下应用的完整独立构建,所有运行时 @lit/localize 代码被移除:
msg调用被替换为每个语言区域的静态本地化版本的字符串或模板。str标签被移除。@lit/localize导入被移除。- 模板被优化,尽可能将不必要的表达式折叠到父模板中。
例如,给定以下源代码:
// src/launch-button.jsimport {msg} from '@lit/localize';
render() { return html`<button>${msg('Launch rocket')}</button>`} 将生成以下文件:
// locales/en/launch-button.jsrender() { return html`<button>Launch rocket</button>`}
// locales/es-419/launch-button.jsrender() { return html`<button>Lanza cohete</button>`} 配置转换模式
Permalink to "配置转换模式"在你的 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',}); 设置初始语言区域
Permalink to "设置初始语言区域"在转换模式下,活动语言区域由你加载的 JavaScript 包决定。如何在页面加载时确定加载哪个包取决于你自己。
例如,如果你应用的语言区域反映在 URL 路径中,你可以在 HTML 文件中包含一个内联脚本来检查 URL 并插入适当的 <script> 标签:
在动态选择脚本名称时,务必验证你的语言区域代码。下面的示例是安全的,因为脚本只有在匹配到我们已知的语言区域代码之一时才能加载,但如果我们的匹配逻辑不够精确,可能会导致注入不安全 JavaScript 的 bug 或攻击。
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 文件中。这让浏览器可以尽早开始下载你的脚本。
切换语言区域
Permalink to "切换语言区域"在转换模式下,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 集成
Permalink to "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';
// 默认从 ./lit-localize.json 读取配置。// 传递路径以从其他位置读取配置。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';
// 默认从 ./lit-localize.json 读取配置。// 传递路径以从其他位置读取配置。const locales = localeTransformers();
export default locales.map(({locale, localeTransformer}) => ({ input: `src/index.js`, plugins: [ typescript({ transformers: { before: [localeTransformer], }, // 指定要发出的 ES 版本和模块格式。参见 // https://www.typescriptlang.org/docs/handbook/tsconfig-json.html tsconfig: 'jsconfig.json', // 转换后的模块在 Rollup 打包之前发出的临时目录。 outDir: 'bundled/temp', // @rollup/plugin-typescript 始终只匹配 ".ts" 文件, // 不管 jsconfig.json 中的任何设置。 include: ['src/**/*.js'], }), resolve(), terser(), summary({ showMinifiedSize: false, }), ], output: { file: `bundled/${locale}/index.js`, format: 'es', sourcemap: true, },}));