要求
关于 Lit 与各种浏览器和工具配合使用的最重要的事情是:
- Lit 以 ES2019 格式发布。
- Lit 使用"裸模块标识符"来导入模块。
- Lit 使用现代 Web API,如
<template>、自定义元素、shadow DOM 和ParentNode。
这些特性受到主流浏览器最新版本(包括 Chrome、Edge、Safari 和 Firefox)和大多数流行工具(如 Rollup、Webpack、Babel 和 Terser)的支持,但浏览器的裸模块标识符支持除外。
在使用 Lit 开发应用时,要么你的目标浏览器需要原生支持这些特性,要么你的工具需要处理它们。虽然有许多浏览器对现代 Web 特性的支持各不相同,但为简单起见,我们建议将浏览器分为两类:
- 现代浏览器支持 ES2019 和 Web Components。工具必须解析裸模块标识符。
- 旧版浏览器支持 ES5,不支持 Web Components 或较新的 DOM API。工具必须编译 JavaScript 并加载 polyfill。
本页概述了如何在开发和生产环境中满足这些要求。
有关满足这些要求的工具和配置建议,请参阅开发、测试和生产环境构建。
现代浏览器的要求
Permalink to "现代浏览器的要求"在现代浏览器上使用 Lit 唯一需要的转换是将裸模块标识符转换为浏览器兼容的 URL。
Lit 使用裸模块标识符在其子包之间导入模块,如下所示:
import {html} from 'lit-html'; 现代浏览器目前只支持从 URL 或相对路径加载模块,不支持引用 npm 包的裸名称,因此构建系统需要处理它们。这应该通过将标识符转换为浏览器中 ES 模块可用的格式,或生成不同类型的模块输出来完成。
Webpack 自动处理裸模块标识符;对于 Rollup,你需要一个插件(@rollup/plugin-node-resolve)。
为什么使用裸模块标识符? 裸模块标识符让你无需确切知道包管理器将它们安装在哪里就能导入模块。一个名为 Import maps 的标准提案正在开始在浏览器中推出,它将让浏览器支持裸模块标识符。在此期间,裸导入标识符可以很容易地作为构建步骤进行转换。也有一些 polyfill 和模块加载器支持 import maps。
现代浏览器版本一览
Permalink to "现代浏览器版本一览"所有现代浏览器都会自动更新,用户很可能拥有最新版本。下表列出了每个主流浏览器原生支持 ES2019 和 Web Components 的最低版本,这是 Lit 依赖的关键特性。
| 浏览器 | 支持 ES2019 和 Web Components |
|---|---|
| Chrome | >=73 |
| Safari | >=12.1 |
| Firefox | >=63 |
| Edge | >=79 |
旧版浏览器的要求
Permalink to "旧版浏览器的要求"支持旧版浏览器(特别是 Internet Explorer 11,以及常青浏览器的旧版本)需要额外的一些步骤:
- 将现代 JavaScript 语法编译为 ES5。
- 将 ES 模块转换为其他模块系统。
- 加载 polyfill。
旧版浏览器版本一览
Permalink to "旧版浏览器版本一览"下表列出了需要编译 JavaScript 和加载 polyfill 的支持浏览器版本:
| 浏览器 | 编译 JS | 编译 JS 并加载 polyfill |
|---|---|---|
| Chrome | 67-79 | <67 |
| Safari | 10-12 | <10 |
| Firefox | 63-71 | <63 |
| Edge | 79 | |
| Edge "经典版" | <=18 | |
| Internet Explorer | 11 |
编译为 ES5
Permalink to "编译为 ES5"Rollup、webpack 和其他构建工具都有插件支持为旧版浏览器编译现代 JavaScript。Babel 是最常用的编译器。
与一些库不同,Lit 以使用现代 ES2019 JavaScript 的 ES 模块集形式发布。当你为旧版浏览器构建应用时,你需要编译 Lit 以及你自己的代码。
如果你已经设置了构建,它可能配置为在编译时忽略 node_modules 文件夹。如果是这种情况,我们建议更新配置以编译 lit 包及其运行时依赖项(lit-html 和 lit-element)。例如,如果你使用的是 Rollup Babel 插件,你可能有如下配置来排除 node_modules 文件夹:
exclude: [ 'node_modules/**' ] 你可以将其替换为明确包含要编译文件夹的规则:
include: [ 'src/**', 'node_modules/lit/**', 'node_modules/lit-element/**', 'node_modules/lit-html/**'] 为什么没有 ES5 构建? Lit 包不包含 ES5 构建,因为现代 JavaScript 更小且通常更快。在构建应用时,你可以根据需要支持的浏览器,将现代 JavaScript 编译为你所需的精确构建版本。
如果 Lit 包含多个构建版本,单个元素可能最终依赖于不同的 Lit 构建版本,导致多个版本的库被发送到浏览器。
在为像 IE11 这样不支持模块的旧版浏览器生成输出时,有三种常见的输出格式:
- 无模块(IIFE)。代码打包为单个文件,包装在立即调用函数表达式(IIFE)中。
- AMD 模块。使用异步模块定义格式;需要模块加载器脚本,如 require.js。
- SystemJS 模块。SystemJS 是一个定义了自己的模块格式的模块加载器。它还支持 AMD、CommonJS 和标准 JavaScript 模块。
如果你的所有代码都可以打包成单个文件,IIFE 格式就足够了。要在像 IE11 这样的旧版浏览器上通过动态 import() 使用代码拆分,你需要生成 AMD 或 SystemJS 模块格式的输出,并加载相应的模块加载器/polyfill。
Polyfill
Permalink to "Polyfill"在旧版浏览器上使用 Lit 需要加载标准 JavaScript 特性(如 Promises 和 async/await)的 polyfill、Web Components polyfill,以及 Lit 包中提供的用于将 Lit 与 Web Components polyfill 进行交互的 polyfill-support 脚本。
以下是推荐的 polyfill:
- JavaScript 特性 polyfill:
core-js- 标准 JS 库regenerator-runtime- 支持生成器和 async/await
- 动态
import()的 polyfill(如果在应用中使用;根据模块转换方式选择): - Web Components polyfill:
@webcomponents/webcomponentsjs- 自定义元素、shadow DOM、template 和一些较新 DOM API 的 polyfilllit/polyfill-support.js-lit包中包含的文件,使用webcomponentsjs时必须加载
请注意,根据你的应用使用的特性,你可能需要其他 polyfill。
加载 polyfill
Permalink to "加载 polyfill"JavaScript polyfill 应该与应用包分开打包,并在 Web Components polyfill 之前加载,因为这些 polyfill 依赖于 Promise 等现代 JS。综合来看,页面应按如下顺序加载代码:
<script src="path/to/js/polyfills/you/need.js"></script><script src="node_modules/lit/polyfill-support.js"></script><script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script><!-- 在此处加载应用代码 --> Web Components polyfill
Permalink to "Web Components polyfill"有关加载和配置 Web Components polyfill 的详细信息,请参阅 webcomponentsjs 文档。以下是一些关键点的摘要。
有两种主要方式来加载 Web Components polyfill:
webcomponents-bundle.js包含在任何支持的浏览器上运行所需的所有 polyfill。因为所有浏览器都会收到所有 polyfill,这会导致向支持一个或多个特性的浏览器发送额外的字节。webcomponents-loader.js在客户端进行特性检测,只加载所需的 polyfill。这需要额外的服务器往返,但为支持一个或多个特性的浏览器节省了带宽。
加载 ES5 适配器
Permalink to "加载 ES5 适配器"最好向现代浏览器提供现代构建,以避免为旧版浏览器发送额外代码。但是,只提供单组文件可能更方便。如果你这样做,有一个额外的必要步骤。为了让 ES5 编译的代码与原生 Web Components(特别是自定义元素)一起工作,需要一个小型适配器。有关详细说明,请参阅 webcomponentsjs 文档。
在任何 Babel polyfill 之后、Web Components polyfill 之前加载 custom-elements-es5-adapter.js,如下所示:
<script src="path/to/js/polyfills/you/need.js"></script><script src="node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script><script src="node_modules/lit/polyfill-support.js"></script><script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script><!-- 在此处加载应用代码 --> 设置 Web Components polyfill 选项
Permalink to "设置 Web Components polyfill 选项"默认情况下,对于原生支持某特性的浏览器,该特性的单独 polyfill 是禁用的。 出于测试目的,你可以强制在有原生支持的浏览器上启用 polyfill。
虽然 Web Components polyfill 努力匹配规范,但在样式方面存在一些不一致(参见 ShadyCSS 限制)。我们建议确保在启用和禁用 polyfill 的情况下都进行测试,无论是在需要它们的浏览器上,还是通过强制启用。你可以在导入 polyfill 之前添加 JavaScript 代码段来强制启用 polyfill:
<script> // 强制启用所有 polyfill if (window.customElements) window.customElements.forcePolyfill = true; ShadyDOM = { force: true }; ShadyCSS = { shimcssproperties: true};</script><script src="./node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script> 或者,如果你使用 webcomponents-bundle.js 文件,你可以通过向应用 URL 添加查询参数来强制启用 polyfill:
https://www.example.com/my-application/view1?wc-ce&wc-shadydom&wc-shimcssproperties
下表列出了每个 polyfill 的 JavaScript 代码段和查询参数。
| Polyfill | JavaScript | 查询参数 |
|---|---|---|
| Custom Elements | if (window.customElements) window.customElements.forcePolyfill = true; | wc-ce |
| Shadow DOM | ShadyDOM = { force: true }; | wc-shadydom |
| CSS 自定义属性 | ShadyCSS = { shimcssproperties: true}; | wc-shimcssproperties |