转换模式
在 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>`
}
配置转换模式
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 的错误或攻击。
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
命令,可以在 Rollup 配置中从 @lit/localize-tools/lib/rollup.js
导入 localeTransformers
函数。
这个函数生成一个 {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,
},
}));