转换本地化模式
在 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>`}配置转换模式
“配置转换模式”的永久链接在您的 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.net.cn/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, },}));