一、背景与目标
在现代前端体系中,Web Components 已成为跨框架共享 UI 组件的核心标准。
它基于浏览器原生能力(Custom Elements、Shadow DOM、HTML Templates、ES Modules),不依赖于特定框架,如 React 或 Vue,可在任意框架项目中直接使用。
而 Lit 框架(前身为 lit-html / lit-element)是 Google 官方推出的轻量级开发工具库,帮助开发者以简洁的方式构建符合 Web Components 标准的组件,拥有以下特点:
- 极小的运行时(≈ 5KB gzipped);
- 支持响应式属性绑定与模板更新;
- 与原生浏览器能力高度兼容;
- 可直接编译输出为可复用组件库。
本篇文章将带你从 0 到 1 构建一套基于 Lit 框架的 Web Component 组件库工程,并实现以下目标:
- ✅ 搭建标准化的组件开发工程;
- ✅ 通过 11ty (Eleventy) 搭建组件文档网站;
- ✅ 使用
@custom-elements-manifest/analyzer自动生成组件 API 文档; - ✅ 引入 Plop.js + AI 大模型测试生成方案;
- ✅ 输出可在任意前端框架中使用的组件包。
二、项目结构规划
我们采用 monorepo + 文档站 模式,将组件源代码与文档系统独立管理:
├── packages/
│ ├── yc-button/
│ │ ├── src/
│ │ │ ├── YcButton.ts
│ │ │ └── style.css
│ │ ├── index.ts
│ │ └── package.json
│ └── yc-card/
│ ├── src/
│ └── index.ts
├── docs-src/
│ ├── index.md
│ ├── components/
│ │ ├── button.md
│ │ └── card.md
│ ├── plugin/
│ │ └── eleventy-plugin-code-demo.cjs
│ ├── docs.css
│ └── .nojekyll
├── .eleventy.cjs
├── package.json
└── tsconfig.json
三、搭建基础工程
1. 初始化项目
mkdir lit-webcomponent-lib && cd lit-webcomponent-lib
npm init -y
npm install lit typescript @webcomponents/webcomponentsjs
2. 创建 tsconfig.json
{
"compilerOptions": {
"target": "ES2021",
"module": "ESNext",
"moduleResolution": "Node",
"outDir": "dist",
"declaration": true,
"emitDecoratorMetadata": false,
"experimentalDecorators": true,
"esModuleInterop": true
},
"include": ["packages/**/*.ts"]
}
四、编写第一个组件
以 yc-button 为例:
// packages/yc-button/src/YcButton.ts
import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';
@customElement('yc-button')
export class YcButton extends LitElement {
static styles = css`
button {
padding: 8px 16px;
background-color: var(--yc-btn-bg, #007bff);
border: none;
border-radius: 4px;
color: #fff;
cursor: pointer;
}
button:hover {
background-color: var(--yc-btn-hover, #0056b3);
}
`;
@property({ type: String }) label = '按钮';
render() {
return html`<button><slot>${this.label}</slot></button>`;
}
}
declare global {
interface HTMLElementTagNameMap {
'yc-button': YcButton;
}
}
导出组件入口:
// packages/yc-button/index.ts
export * from './src/YcButton.js';
五、自动化文档系统搭建
文档系统采用 11ty (Eleventy) 构建。
它是一款极轻量静态网站生成器,使用 Markdown + 模板语法快速生成静态页面,非常适合 Web Component 文档场景。
1. 安装依赖
npm install @11ty/eleventy @11ty/eleventy-plugin-syntaxhighlight
2. 创建 .eleventy.cjs 配置文件
// .eleventy.cjs
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
const codeDemoPlugin = require("./docs-src/plugin/eleventy-plugin-code-demo.cjs");
module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(syntaxHighlight);
eleventyConfig.addPlugin(codeDemoPlugin);
eleventyConfig.addPassthroughCopy('docs-src/docs.css');
eleventyConfig.addPassthroughCopy('docs-src/.nojekyll');
eleventyConfig.addPassthroughCopy(
'node_modules/@webcomponents/webcomponentsjs'
);
eleventyConfig.addPassthroughCopy('node_modules/lit/polyfill-support.js');
return {
dir: {
input: 'docs-src',
output: 'docs',
},
templateExtensionAliases: {
'11ty.cjs': '11ty.js',
'11tydata.cjs': '11tydata.js',
},
};
};
3. 编写文档模板示例
在 docs-src/components/button.md 中添加组件文档内容:
---
title: YcButton 按钮组件
layout: base.njk
---
# `<yc-button>` 按钮组件
用于触发用户操作的基础按钮组件。
## 示例
```html
<yc-button label="点击我"></yc-button>
属性 (Props)
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label | string | '按钮' | 按钮文字 |
样式变量
| 变量名 | 说明 |
|---|---|
--yc-btn-bg | 按钮背景色 |
--yc-btn-hover | 悬停背景色 |
其中 `<code-demo>` 标签由 `eleventy-plugin-code-demo.cjs` 提供,用于在 Markdown 中嵌入组件预览。
示例插件(简化版):
```js
// docs-src/plugin/eleventy-plugin-code-demo.cjs
module.exports = (eleventyConfig) => {
eleventyConfig.addPairedShortcode("code-demo", (content) => {
return `<div class="demo">${content}</div>
<pre><code>${content.replace(/</g, "<").replace(/>/g, ">")}</code></pre>`;
});
};
六、组件 API 自动化生成
通过 @custom-elements-manifest/analyzer 工具自动提取组件属性、事件、插槽信息,生成标准的 custom-elements.json。
安装与使用
npm install @custom-elements-manifest/analyzer --save-dev
在项目根目录添加 analyze.mjs:
import { analyze } from '@custom-elements-manifest/analyzer';
import fs from 'fs';
const result = await analyze({
globs: ['packages/**/src/*.ts'],
});
fs.writeFileSync(
'custom-elements.json',
JSON.stringify(result, null, 2)
);
运行命令:
node analyze.mjs
生成后的 custom-elements.json 将被 Eleventy 文档系统读取并展示 API。
七、引入 Plop.js + AI 生成测试用例方案
在大型组件库中,重复编写单测文件成本高,因此引入 Plop.js 模板引擎 + AI 自动生成逻辑测试代码。
1. 安装依赖
npm install plop @types/node --save-dev
2. 新建 plopfile.cjs
module.exports = function (plop) {
plop.setGenerator('test', {
description: '生成组件测试文件',
prompts: [
{
type: 'input',
name: 'component',
message: '请输入组件名称:',
},
],
actions: [
{
type: 'add',
path: 'packages/{{component}}/test/{{component}}.spec.ts',
templateFile: 'plop-templates/test.hbs',
},
],
});
};
3. 模板文件示例
// packages/{{component}}/test/{{component}}.spec.ts
import { fixture, html } from '@open-wc/testing';
import '../src/{{component}}.js';
describe('{{component}}', () => {
it('should render properly', async () => {
const el = await fixture(html`<{{component}}></{{component}}>`);
expect(el).to.exist;
});
});
4. 结合 AI 生成逻辑性用例
通过内部大模型 API(如 OpenAI GPT)分析组件 @property 属性与 DOM 行为,生成更多逻辑测试用例:
npx plop test
执行后输入组件名,如 yc-button,即可自动生成并补全测试文件内容。
八、构建与发布
构建组件库
使用 tsc 直接编译:
npx tsc
输出结果将包含 dist/ 目录内的所有 Web Components。
发布至 npm
npm publish --access public
九、总结与展望
本文完整介绍了从 Lit + Web Components 工程搭建 → Eleventy 文档系统 → 自动化测试方案 → API 生成 的全链路实践。
通过这套体系,你可以:
- 轻松构建高复用组件;
- 输出清晰的自动化文档;
- 快速生成测试样例;
- 实现跨框架复用(Vue、React、Angular、纯 HTML)。
未来可进一步扩展:
- 自动生成 Demo 预览组件;
- 集成 Storybook 或 VitePress;
- 使用 GitHub Actions 实现文档自动部署。
✅ 项目亮点回顾
| 模块 | 技术 | 功能 |
|---|---|---|
| 组件开发 | Lit | 构建标准化 Web Component |
| 文档系统 | Eleventy + Markdown | 自动生成静态文档 |
| 代码高亮 | @11ty/eleventy-plugin-syntaxhighlight | 提升可读性 |
| 组件演示 | 自定义 code-demo 插件 | 可交互 Demo |
| API 自动化 | @custom-elements-manifest/analyzer | 自动提取组件属性 |
| 测试体系 | Plop.js + AI | 自动生成单测模板 |
文章评论