Lit 3 升级指南

如果你正在寻找从 Lit 1.x 迁移到 Lit 2.x 的指南,请参阅 Lit 2 升级指南

Lit 3.0 相比 Lit 2.x 只有很少的破坏性变更:

  • 不再支持 IE11。
  • Lit 的 npm 模块现在以 ES2021 格式发布。
  • Lit 2.x 版本中标记为已弃用的 API 已被移除。
  • SSR 水合支持模块已移至 @lit-labs/ssr-client 包。
  • 仅类型变更:ReactiveElementrenderRootcreateRenderRoot() 的类型已更新。
  • 移除了对 Babel 装饰器版本 "2018-09" 的支持。
  • TypeScript 实验性装饰器和标准装饰器之间的行为已统一。
    • 因此,如果你使用 TypeScript,你需要升级到至少 TypeScript v5.2,以获取两种装饰器的更新类型。

对于绝大多数用户,从 Lit 2 升级到 Lit 3 不需要任何代码更改。大多数应用和库可以扩展它们的 npm 版本范围以同时包含 2.x 和 3.x,例如 "^2.7.0 || ^3.0.0"

Lit 2.x 和 3.0 是可互操作的 - 一个版本的 Lit 的模板、基类和指令将与另一个版本的对应部分一起工作。

Lit 2 是以 ES2019 格式发布的,而 Lit 3 现在以 ES2021 格式发布,这在现代浏览器和构建工具中得到了广泛支持。 如果你需要支持较旧的浏览器版本并且你当前的工具无法解析 ES2021,这可能是一个破坏性变更。

Webpack 4 的内部解析器不支持空值合并运算符(??)、逻辑赋值运算符(??=)或可选链(?.),这些是 ES2021 引入的语法,因此在遇到这些语法时会抛出 Module parse failed: Unexpected token 错误。

首选的解决方案是升级到支持解析这些较新 JS 语法的 Webpack 5。但是,如果你无法这样做,可以使用 babel-loader 来转换 Lit 3 代码,使其与 Webpack 4 兼容。

要在 Webpack 4 中转译 Lit 3,请安装以下必需的 babel 包:

并添加一个类似于以下的新规则(你可能需要根据你的特定项目进行修改):

JavaScript 装饰器最近已被 TC39 标准化,并处于四阶段标准化过程的第 3 阶段。第 3 阶段是 JavaScript 实现(如虚拟机和编译器)开始实施稳定规范的阶段。TypeScript 5.2 和 Babel 7.23 最近已经实现了该标准。

这意味着装饰器 API 存在多个版本:标准装饰器、TypeScript 的实验性装饰器,以及 Babel 之前实现的提案,如版本 "2018-09"。

虽然 Lit 2 支持 TypeScript 实验性装饰器和 Babel 的 "2018-09" 装饰器,但 Lit 3 现在支持标准装饰器和 TypeScript 实验性装饰器。

Lit 3 装饰器大多向后兼容 Lit 2 TypeScript 装饰器 - 很可能不需要任何更改

为了使 Lit 装饰器在实验性和标准装饰器模式之间的行为保持一致,一些小的破坏性变更是必要的。

Lit 3.0 中 Lit 装饰器行为的变化:

如果你的 Lit 2.x 项目没有弃用警告,你应该不会受到这个列表的影响。

移除 UpdatingElement 作为 ReactiveElement 的别名

Permalink to "移除 UpdatingElement 作为 ReactiveElement 的别名"

将 Lit 2.x 中使用的 UpdatingElement 替换为 ReactiveElement。这不是功能性变更,因为 UpdatingElementReactiveElement 的别名。

lit-element 中移除装饰器的重新导出

Permalink to "从 lit-element 中移除装饰器的重新导出"

Lit 3.0 内置装饰器不再从 lit-element 导出,而应该从 lit/decorators.js 导入。

已移除已弃用的 queryAssignedNodes(slot: string, flatten: bool, selector: string) 装饰器签名

Permalink to "已移除已弃用的 queryAssignedNodes(slot: string, flatten: bool, selector: string) 装饰器签名"

将任何使用带选择器的 queryAssignedNodes 的用法迁移为使用 queryAssignedElements

没有 selector 的用法现在必须使用选项对象。

litlit-elementlit-html 中移除服务器端渲染实验性水合模块

Permalink to "从 lit、lit-element 和 lit-html 中移除服务器端渲染实验性水合模块"

实验性水合支持已从核心库移出,并移至 @lit-labs/ssr-client

[仅类型]:已更新 renderRootcreateRenderRoot() 的类型

Permalink to "[仅类型]:已更新 renderRoot 和 createRenderRoot() 的类型"

这只是类型变更,没有运行时影响。

ReactiveElement.renderRoot 的类型从 Element | ShadowRoot 变更为 HTMLElement | DocumentFragmentReactiveElement.createRenderRoot() 的返回类型从 HTMLElement | ShadowRoot 变更为 HTMLElement | DocumentFragment。这使它们与彼此以及 lit-html 的 render() 保持一致。

这个变更通常不会影响仅访问 this.renderRoot 的代码。但是,任何具有其先前类型的显式类型标注的代码都应该更新。

虽然 Lit 3 添加了对标准装饰器的支持,但我们仍然建议 TypeScript 用户继续使用实验性装饰器。这是因为目前 TypeScript 和 Babel 编译器为标准装饰器生成的代码相当庞大。

当浏览器支持标准装饰器,或者当我们在新的 Lit 编译器中发布装饰器转换支持时,我们将推荐在生产环境中使用标准装饰器。

但你现在可以尝试标准装饰器,它们在 TypeScript 5.2 及更高版本以及带有 @babel/plugin-proposal-decorators 插件的 Babel 7.23 中有效。

安装 TypeScript 5.2 或更高版本,并在 tsconfig 中 移除 "experimentalDecorators" 设置(如果存在)。

安装 Babel 7.23 或更高版本,以及 @babel/plugin-proposal-decorators。确保向该插件传递 "version": "2023-05" 选项。

向装饰字段添加 accessor 关键字

Permalink to "向装饰字段添加 accessor 关键字"

标准装饰器不允许更改它们装饰的类成员的 类型。需要创建 getter 和 setter 的装饰器必须应用于现有的 getter 和 setter。为了使这更符合人体工程学,装饰器标准添加了 accessor 关键字,当应用于类字段时,它会创建"自动访问器"。自动访问器看起来和表现得很像类字段,但在原型上创建由私有存储支持的访问器。

@property()@state()@query()@queryAll()@queryAssignedElements()@queryAssignedNode() 装饰器需要 accessor 关键字。

示例:

将装饰器从 getter 移到 setter

Permalink to "将装饰器从 getter 移到 setter"

标准装饰器只能替换它们直接应用的类成员。Lit 装饰器需要拦截属性设置,因此装饰器必须应用于 setter。这与 Lit 2 推荐的将装饰器应用于 getter 不同。

对于 @property()@state(),你还可以移除 setter 中的任何 this.requestUpdate() 调用,因为现在会自动执行此操作。如果你需要 调用 requestUpdate(),你必须使用 noAccessor 属性选项。

请注意,对于 @property()@state(),装饰器在设置属性时会调用 getter 以检索旧值。这意味着你 必须 同时定义 getter 和 setter。

之前:

之后: