生产环境构建
本页重点介绍使用 Lit 组件构建_应用_以用于生产环境的建议。有关在将可复用的 Lit _组件_发布到 npm 之前对源代码执行的构建步骤建议,请参阅发布。
在构建包含 Lit 组件的应用时,你可以使用常见的 JavaScript 构建工具(如 Rollup 或 webpack)来准备源代码和依赖项,以便在生产环境中提供服务。
有关构建 Lit 代码的完整要求列表,请参阅要求,这些要求适用于开发和生产环境。
除了这些最低要求外,本页还描述了在准备生产环境代码时应考虑的优化,以及实现了这些优化的具体 Rollup 配置。
准备生产环境代码
Permalink to "准备生产环境代码"Lit 项目受益于与其他 Web 项目相同的构建时优化。在生产环境中提供 Lit 应用时,建议进行以下优化:
- 打包 JavaScript 模块以减少网络请求(例如,使用 Rollup 或 webpack)。
- 压缩 JavaScript 代码以减小有效负载大小(Terser 非常适合 Lit,因为它支持现代 JavaScript)。
- 向现代浏览器提供现代代码,因为现代代码通常更小更快,并在旧版浏览器上回退到编译后的代码。
- 对静态资源(包括打包后的 JavaScript)进行哈希处理以便于缓存失效。
- 启用服务端压缩(如 gzip 或 brotli)以减少传输字节数。
此外,请注意,由于 Lit 模板在 JavaScript 模板字符串字面量中定义,它们不会被标准 HTML 压缩器处理。添加一个压缩模板字符串字面量中 HTML 的插件可以适度减小代码体积。有几个包可以执行此优化:
使用 Rollup 构建
Permalink to "使用 Rollup 构建"你可以使用许多工具来执行提供 Lit 代码所需的必要和可选构建步骤,Lit 不要求使用任何特定工具。但是,我们推荐 Rollup,因为它设计用于处理标准 ES 模块格式,并输出利用客户端原生模块的优化代码。
有许多方法可以设置 Rollup 来打包你的项目。Modern Web 项目维护了一个出色的 Rollup 插件 @web/rollup-plugin-html,它将许多构建应用的最佳实践整合到一个易于使用的包中。以下是使用此插件的配置示例。
仅现代浏览器构建
Permalink to "仅现代浏览器构建"下面带注释的 rollup.config.js 文件将构建一个满足现代浏览器构建要求和本页描述的生产环境优化的应用。此配置适用于能够运行 ES2019 JS 而无需 polyfill 的现代浏览器。
所需的 Node 模块:
npm i --save-dev rollup \ @web/rollup-plugin-html \ @web/rollup-plugin-copy \ @rollup/plugin-node-resolve \ @rollup/plugin-terser \ rollup-plugin-minify-html-literals \ rollup-plugin-summary rollup.config.js:
// 导入 Rollup 插件import html from '@web/rollup-plugin-html';import {copy} from '@web/rollup-plugin-copy';import resolve from '@rollup/plugin-node-resolve';import {terser} from '@rollup/plugin-terser';import minifyHTML from 'rollup-plugin-minify-html-literals';import summary from 'rollup-plugin-summary';
export default { plugins: [ // 应用构建的入口点;可以指定 glob 来为非 SPA 应用构建多个 HTML 文件 html({ input: 'index.html', }), // 将裸模块标识符解析为相对路径 resolve(), // 压缩 HTML 模板字面量 minifyHTML(), // 压缩 JS terser({ ecma: 2020, module: true, warnings: true, }), // 打印包摘要 summary(), // 可选:将静态资源复制到构建目录 copy({ patterns: ['images/**/*'], }), ], output: { dir: 'build', }, preserveEntrySignatures: 'strict',}; 运行 Rollup 构建:
rollup -c 现代 + 旧版浏览器构建
Permalink to "现代 + 旧版浏览器构建"以下配置生成一个混合构建,包含两组 JS 包,一组用于现代浏览器,一组用于旧版浏览器。现代包被乐观地预取,客户端特性检测用于确定是加载更小/更快的现代构建还是旧版构建(以及任何所需的 polyfill),按照旧版浏览器构建要求。
所需的 Node 模块:
npm i --save-dev rollup \ @web/rollup-plugin-html \ @web/rollup-plugin-polyfills-loader \ @web/rollup-plugin-copy \ @rollup/plugin-node-resolve \ @rollup/plugin-babel \ @rollup/plugin-terser \ rollup-plugin-minify-html-literals \ rollup-plugin-summary rollup.config.js:
// 导入 Rollup 插件import html from '@web/rollup-plugin-html';import polyfillsLoader from '@web/rollup-plugin-polyfills-loader';import {copy} from '@web/rollup-plugin-copy';import resolve from '@rollup/plugin-node-resolve';import {getBabelOutputPlugin} from '@rollup/plugin-babel';import {terser} from 'rollup-plugin-terser';import minifyHTML from 'rollup-plugin-minify-html-literals';import summary from 'rollup-plugin-summary';
// 配置 @web/rollup-plugin-html 的实例const htmlPlugin = html({ rootDir: './', flattenOutput: false,});
export default { // 应用构建的入口点;可以指定 glob 来为非 SPA 应用构建多个 HTML 文件 input: 'index.html', plugins: [ htmlPlugin, // 将裸模块标识符解析为相对路径 resolve(), // 压缩 HTML 模板字面量 minifyHTML(), // 压缩 JS terser({ module: true, warnings: true, }), // 将 polyfill 注入到 HTML 中(core-js、regnerator-runtime、webcoponents、 // lit/polyfill-support),并动态加载现代或旧版构建 polyfillsLoader({ modernOutput: { name: 'modern', }, // 用于加载旧版包的特性检测 legacyOutput: { name: 'legacy', test: '!!Array.prototype.flat', type: 'systemjs', }, // 要注入的 polyfill 列表(每个都有单独的特性检测) polyfills: { hash: true, coreJs: true, regeneratorRuntime: true, fetch: true, webcomponents: true, // 加载 Lit 的 polyfill-support 模块的自定义配置, // 这是与 webcomponents polyfill 交互所必需的 custom: [ { name: 'lit-polyfill-support', path: 'node_modules/lit/polyfill-support.js', test: "!('attachShadow' in Element.prototype)", module: false, }, ], }, }), // 打印包摘要 summary(), // 可选:将静态资源复制到构建目录 copy({ patterns: ['data/**/*', 'images/**/*'], }), ], // 指定两个 JS 输出配置(现代和旧版),HTML 插件会自动在它们之间选择; // 旧版构建编译为 ES5 和 SystemJS 模块 output: [ { // 现代 JS 包(无 JS 编译,ES 模块输出) format: 'esm', chunkFileNames: '[name]-[hash].js', entryFileNames: '[name]-[hash].js', dir: 'build', plugins: [htmlPlugin.api.addOutput('modern')], }, { // 旧版 JS 包(ES5 编译和 SystemJS 模块输出) format: 'esm', chunkFileNames: 'legacy-[name]-[hash].js', entryFileNames: 'legacy-[name]-[hash].js', dir: 'build', plugins: [ htmlPlugin.api.addOutput('legacy'), // 使用 Babel 将 JS 编译为 ES5,将模块转换为 SystemJS getBabelOutputPlugin({ compact: true, presets: [ [ '@babel/preset-env', { targets: { ie: '11', }, modules: 'systemjs', }, ], ], }), ], }, ], preserveEntrySignatures: false,}; 使用独立的 lit-html 构建
Permalink to "使用独立的 lit-html 构建"如果你将 lit-html 作为独立的模板库使用,你可以遵循几乎所有的 Lit 构建指导。唯一的区别是 lit-html 不需要完整的 Web Components polyfill。你只需要 template polyfill。
使用 template polyfill
Permalink to "使用 template polyfill"要在不支持 <template> 元素的 Internet Explorer 11 上运行 lit-html,你需要一个 polyfill。你可以使用 Web Components polyfill 中包含的 template polyfill。
安装 template polyfill:
npm i @webcomponents/template 使用 template polyfill:
<script src="./node_modules/@webcomponents/template/template.min.js"></script> 注意:在为 IE11 编译时,Babel polyfill 需要与应用代码分开打包,并在 template polyfill _之前_加载。