Lit 3.0 入门实战:基于 lit-starter-js 模板构建 JavaScript Web Components 的完整开发流程
2026/9/13 2:11:41 网站建设 项目流程

Lit 3.0 入门实战:基于 lit-starter-js 模板构建 JavaScript Web Components 的完整开发流程

【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/lit

Lit 是一个用于构建快速、轻量级 Web Components 的简单库。lit-starter-js是 Lit 官方仓库中基于 JavaScript(无需 TypeScript 编译)的入门模板,它内置了一个示例组件<my-element>,并预配置了测试、开发服务器、代码检查、格式化与静态站点生成等一整套现代前端工程设施。读完本文,你将掌握如何基于该模板快速搭建自己的 LitElement 组件项目,理解 dev/prod 双模式运行与测试机制,并学会如何将组件发布为可复用的 Web Components。

模板概览:一个开箱即用的 LitElement JavaScript 项目

lit-starter-js位于本仓库的 packages/lit-starter-js 目录,它提供了一个纯 JavaScript 的 LitElement 示例组件,核心文件是 my-element.js。该项目直接以 ES Module 方式运行,package.json中声明了"type": "module"(见 package.json),因此所有源码无需编译即可在现代浏览器中加载,这正是"starter"模板的核心价值——把工程化的复杂度交给工具链,让开发者专注于组件本身。

模板依赖的核心运行时为lit包("^3.2.0"),开发期工具链则包括:

  • @web/dev-server:开发服务器,负责解析浏览器不支持的 Node 风格裸模块导入(bare import specifiers),并自动转译 JavaScript、注入 polyfill 以兼容旧浏览器;
  • @web/test-runner:基于现代 Web 标准的测试运行器,配合 Playwright 在真实浏览器中执行单元测试;
  • @custom-elements-manifest/analyzer:从源码生成自定义元素清单(custom-elements.json),供文档站点与 lit-plugin 使用;
  • @11ty/eleventy:静态站点生成器,用于生成组件文档站点;
  • rollup+ terser`:用于文档站点的打包与压缩(注意:并非用于 NPM 发布);
  • eslint+lit-analyzer:代码检查与 lit-html 模板的类型检查/静态分析;
  • prettier:代码格式化。

这些依赖均可在 package.json 的devDependencies中逐一核对。

示例组件<my-element>源码导读

模板的核心示例组件定义在 my-element.js:

import {LitElement, html, css} from 'lit'; export class MyElement extends LitElement { static get styles() { return css` :host { display: block; border: solid 1px gray; padding: 16px; max-width: 800px; } `; } static get properties() { return { name: {type: String}, count: {type: Number}, }; } constructor() { super(); this.name = 'World'; this.count = 0; } render() { return html` <h1>${this.sayHello(this.name)}!</h1> <button @click=${this._onClick} part="button"> Click Count: ${this.count} </button> <slot></slot> `; } _onClick() { this.count++; this.dispatchEvent(new CustomEvent('count-changed')); } sayHello(name) { return `Hello, ${name}`; } } window.customElements.define('my-element', MyElement);

这个组件演示了 LitElement 的全部核心概念:

  • 响应式属性(reactive properties):通过static get properties()声明name(String 类型)与count(Number 类型)。当属性变化时,Lit 会自动触发重新渲染;
  • 声明式模板render()返回html标签模板,其中${this.sayHello(this.name)}为文本插值、@click=${this._onClick}为事件绑定、part="button"暴露可被外部通过::part()样式化的 CSS 部分;
  • 样式封装css标签模板配合:host选择器,样式被 Shadow DOM 隔离,不会泄漏到外部文档;
  • 插槽(slot)<slot></slot>允许使用者将子内容投影进组件内部;
  • 自定义事件:点击按钮时dispatchEvent(new CustomEvent('count-changed'))向外通知状态变化;
  • 注册自定义元素:文件末尾window.customElements.define('my-element', MyElement)将类注册为可用的 HTML 标签。

环境准备与项目安装

开始开发前,先安装项目依赖:

npm i

安装完成后,即可使用下文介绍的测试、开发服务器、代码检查与文档生成等全部命令。所有可用的 npm 脚本定义在 package.json,下文逐一展开。

测试:在真实浏览器中验证组件行为

模板使用 modern-web.dev 的 @web/test-runner。

双模式测试机制:dev 与 prod

模板的一个重要设计是同一套测试分别运行在 Lit 的开发模式与生产模式下

npm test

npm test实际串联执行test:devtest:prod(见 package.json)。其底层原理通过MODE环境变量控制nodeResolveexportConditions

const mode = process.env.MODE || 'dev'; if (!['dev', 'prod'].includes(mode)) { throw new Error(`MODE must be "dev" or "prod", was "${mode}"`); } export default { rootDir: '.', files: ['./test/**/*_test.js'], nodeResolve: {exportConditions: mode === 'dev' ? ['development'] : []}, // ... };

MODE=dev时,exportConditions: ['development']会命中lit包中带有"development"导出条件的开发构建——该构建包含更详细的错误信息(例如属性类型不匹配、模板渲染异常等更易读的提示);当MODE=prod时则加载生产构建,验证代码在优化后的真实发布形态下依然正确。

在开发迭代期间,可用以下命令实现文件变更后自动重跑:

npm test:watch # dev 模式 + 监听 npm run test:prod:watch # prod 模式 + 监听

浏览器启动器与云端测试平台

测试配置通过 Playwright 启动真实浏览器,默认覆盖 Chromium、Firefox、WebKit 三个内核(web-test-runner.config.js):

const browsers = { chromium: playwrightLauncher({product: 'chromium'}), firefox: playwrightLauncher({product: 'firefox'}), webkit: playwrightLauncher({product: 'webkit'}), };

同时支持通过BROWSERS环境变量只运行指定浏览器子集,例如:

BROWSERS=chromium,firefox npm run test

配置文件内还注释保留了 Sauce Labs 与 BrowserStack 等云端浏览器测试平台的接入示例(web-test-runner.config.js),按需取消注释并安装对应启动器包、设置环境变量即可。

旧浏览器兼容与 polyfill 注入

测试配置通过legacyPlugin处理不支持 ES Modules 的旧浏览器(如 IE11),同时为测试文件注入 Lit 的 polyfill 支持模块:

legacyPlugin({ polyfills: { webcomponents: true, custom: [ { name: 'lit-polyfill-support', path: 'node_modules/lit/polyfill-support.js', test: "!('attachShadow' in Element.prototype) || !('getRootNode' in Element.prototype) || window.ShadyDOM && window.ShadyDOM.force", module: false, }, ], }, }),

这段配置的背景是:webcomponents polyfill 会模拟 Shadow DOM,而 Lit 需要与该 polyfill 对接才能正常工作,因此必须在 polyfill 之后注入 polyfill-support.js(path: 'node_modules/lit/polyfill-support.js')。test字段用于探测当前浏览器是否真的需要这些 polyfill(例如检测attachShadowgetRootNode是否存在或是否强制使用 ShadyDOM),从而避免在现代浏览器中做无用功。

模板自带的测试用例

测试文件 test/my-element_test.js 使用@open-wc/testing提供的fixtureassert,以 TDD 风格(Mochaui: 'tdd')编写了四个用例:

  1. 元素已注册document.createElement('my-element')MyElement的实例;
  2. 默认值渲染:未传任何属性时,Shadow DOM 渲染为<h1>Hello, World!</h1>Click Count: 0
  3. 属性驱动渲染:传入name="Test"时渲染Hello, Test!
  4. 交互行为:模拟点击按钮后count变为 1,并通过await el.updateComplete等待更新完成后断言结果;
  5. 样式生效:断言getComputedStyle(el).paddingTop === '16px',验证:host中的样式确实被应用。

这些用例可作为你为自定义组件编写测试的范式:用fixture挂载组件、用assert.shadowDom.equal断言渲染结果、用updateComplete等待异步更新。

开发服务器:零构建预览组件

模板使用 modern-web.dev 的 @web/dev-server 提供开发预览。它的核心能力是解析浏览器原生不支持的 Node 风格"裸"导入说明符(例如源码中的import {LitElement} from 'lit'),并将模块解析为浏览器可加载的 URL;同时自动转译 JavaScript 并添加 polyfill 以支持旧浏览器。

启动开发服务器:

npm run serve

该命令会以开发模式(MODE 默认为dev)启动 Web Dev Server,并开启--watch文件监听。开发用的 HTML 页面位于 dev/index.html,访问地址为:

http://localhost:8000/dev/index.html

以生产模式启动则使用:

npm run serve:prod

它等价于MODE=prod npm run serve(见 package.json)。

serveserve:prod的差异同样由 web-dev-server.config.js 中的exportConditions控制:

const mode = process.env.MODE || 'dev'; export default { nodeResolve: {exportConditions: mode === 'dev' ? ['development'] : []}, preserveSymlinks: true, plugins: [ legacyPlugin({ polyfills: { webcomponents: false, // 在 index.html 中手动引入 }, }), ], };

注意开发服务器的 legacy 配置中webcomponents: false,这是因为 dev/index.html 已经手动引入了webcomponentsjs加载器与 Lit 的 polyfill-support:

<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script> <script src="../node_modules/lit/polyfill-support.js"></script> <script type="module" src="../my-element.js"></script>

preserveSymlinks: true则保证在 monorepo 或 npm link 场景下模块解析的一致性。

演示页面

dev/index.html 将<my-element>与一段子内容组合使用:

<my-element> <p>This is child content</p> </my-element>

子内容<p>会通过组件模板中的<slot>被投影进组件内部,直观演示了 Web Components 的插槽机制。根目录的 index.html 则只是一个指向/dev/index.html的入口页。

编辑器支持:推荐 VS Code 与 lit-plugin

如果你使用 VS Code,官方强烈推荐安装 lit-plugin 扩展,它为 lit-html 模板提供以下能力:

  • 语法高亮(Syntax highlighting)
  • 类型检查(Type-checking)
  • 代码补全(Code completion)
  • 悬停文档(Hover-over docs)
  • 跳转到定义(Jump to definition)
  • 代码检查(Linting)
  • 快速修复(Quick Fixes)

模板已配置好对 lit-plugin 的推荐(workspace recommendations),VS Code 用户首次打开项目时会收到安装提示。lit-plugin 的底层分析引擎与lit-analyzer相同,因此编辑器内的检查结果与命令行 lint 结果保持一致。

代码检查与格式化

ESLint 与 lit-analyzer

JavaScript 文件的代码检查由 ESLint 提供,此外 lit-analyzer 会以与 lit-plugin 相同的引擎和规则对 lit-html 模板进行类型检查与静态分析。执行:

npm run lint

该命令实际串联执行lint:eslint(对**/*.js运行 ESLint)与lint:lit-analyzer(对my-element.js运行 lit-analyzer),见 package.json。

模板采用的是各工具官方推荐的规则集,但部分规则被关闭以降低 LitElement 的使用门槛(例如某些对模板表达式过于严格的检查)。这些推荐规则本身相当严格,如果你觉得约束过多,可以编辑项目中的 ESLint 配置文件(.eslintrc.json)按需放宽。

Prettier 格式化

代码格式化由 Prettier 负责,并已按 Lit 项目的代码风格预配置,可通过.prettierrc.json调整。执行格式化:

npm run format

Prettier 默认未接入提交前钩子(pre-commit hook),但文档建议可以自行通过 Husky 配合pretty-quick实现提交前自动格式化。

静态站点:用 Eleventy 生成组件文档

模板内置了一个基于 eleventy 目录,生成产物输出到docs目录。该站点的设计目的是配合 GitHub Pages:将 GitHub Pages 的 "Source" 设置为 "main branch /docs folder",即可让docs目录下的静态文件直接作为站点发布。

站点构建涉及如下命令(定义见 package.json):

npm run docs # 完整构建站点 npm run docs:serve # 本地预览站点(http://localhost:8000) npm run docs:gen:watch # 监听站点源文件并自动重新构建

npm run docs是一条流水线,依次执行:

  1. docs:clean:使用rimraf清理旧的docs目录;
  2. analyze:使用cem analyze --litelement(Custom Elements Manifest Analyzer)扫描**/*.js源码,生成custom-elements.json元素清单;
  3. docs:build:通过 Rollup 将 my-element.js 打包并压缩为docs/my-element.bundled.js
  4. docs:assets:复制 Prism 主题样式到docs/
  5. docs:gen:运行eleventy --config=.eleventy.cjs生成 HTML 页面。

站点源文件结构如下:

  • docs-src/index.md:站点首页,演示了<my-element>的三种用法——纯 HTML 使用、通过 attribute 配置(<my-element name="HTML">)、以及与 lit-html 等声明式渲染库配合(使用.name=${name}属性绑定);
  • docs-src/examples/name-property.md:示例页面,展示name="Earth"的效果;
  • docs-src/_includes:Eleventy 的布局模板(header、footer、nav、page 等);
  • docs-src/_README.md:说明站点源与构建流程的关系。

analyze命令生成的custom-elements.json是标准化的自定义元素清单格式,除了驱动文档站点中的 API 页面(docs-src/api.11ty.cjs)之外,也被 lit-plugin 等工具用于提供更精确的补全与类型信息。

打包与压缩:理解模板的 Rollup 定位

模板的 rollup.config.js 负责将my-element.js及其依赖打包为单个 ESM 文件my-element.bundled.js,并做压缩处理:

export default { input: 'my-element.js', output: {file: 'my-element.bundled.js', format: 'esm'}, plugins: [ replace({preventAssignment: false, 'Reflect.decorate': 'undefined'}), resolve(), terser({ecma: 2021, module: true, warnings: true}), summary(), ], };

其中replaceReflect.decorate替换为undefined(避免未使用的装饰器 shim 代码被保留)、resolve解析 node_modules 依赖、terser以 ES2021 为目标做压缩、summary输出打包体积摘要。npm run checksize命令会执行打包后用 gzip 统计产物字节数,用于评估组件体积。

需要特别澄清:这套 Rollup 配置仅服务于文档站点的生成(让docs页面能引用打包后的组件脚本),并不用于 NPM 发布。Lit 官方推荐的发布策略是:将组件作为未优化的原生 JavaScript 模块发布,把构建期优化留给应用程序层——这样构建工具才能最大程度地对依赖做去重(deduplication)与死代码消除(tree-shaking)。关于发布可复用 Web Components 的最佳实践,以及如何为包含 LitElement 组件的应用做生产构建,可参考 Lit 官方文档中的 "Publishing best practices" 与 "Build for production" 章节。

关于 Lit 3.0 预发布版本

当前模板对应的是Lit 3.0 预发布版本(模板的lit依赖为^3.2.0)。Lit 3.0 相比 2.0 的破坏性变更非常少,主要包括:

  • 放弃对 IE11 的支持
  • 以 ES2021 为目标发布
  • 移除少量已废弃的 Lit 1.x API

因此,对绝大多数用户而言,从 Lit 2.0 升级到 3.0无需修改任何代码。完整版发布后,多数应用与库可以直接将 npm 版本范围扩展为同时兼容 2.x 与 3.x,例如:

"^2.7.0 || ^3.0.0"

Lit 2.x 与 3.0 是互相可互操作的(interoperable):一个版本的模板、基类、指令(directives)、装饰器(decorators)等可以与另一版本配合使用。

快速上手:三步跑通整个模板

最后,将上述所有环节浓缩为可复制的三步流程:

# 1. 安装依赖 npm i # 2. 启动开发服务器,打开 http://localhost:8000/dev/index.html 预览组件 npm run serve # 3. 运行测试(dev + prod 双模式)、代码检查与格式化 npm test npm run lint npm run format

如需为文档站点构建静态页面,运行npm run docs后通过npm run docs:servehttp://localhost:8000预览。掌握了这套流程,你就可以把 my-element.js 替换为自己的组件,开始用 Lit 3.0 构建快速、轻量级的 Web Components 了。

【免费下载链接】litLit is a simple library for building fast, lightweight web components.项目地址: https://gitcode.com/GitHub_Trending/li/lit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询