蓝戒博客

  • 首页
  • 研发说
  • 架构论
  • 效能录
  • AI谈
  • 随笔集
智构苍穹
融合 AI、架构与工程实践,沉淀方法论,构建可持续的技术价值。
  1. 首页
  2. 研发说
  3. 正文

基于 Lit 框架开发 Web Component 组件的完整实践

2025年10月6日 901点热度 2人点赞 0条评论

一、背景与目标

在现代前端体系中,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. 初始化项目

Bash
mkdir lit-webcomponent-lib && cd lit-webcomponent-lib
npm init -y
npm install lit typescript @webcomponents/webcomponentsjs

2. 创建 tsconfig.json

JSON
{
  "compilerOptions": {
    "target": "ES2021",
    "module": "ESNext",
    "moduleResolution": "Node",
    "outDir": "dist",
    "declaration": true,
    "emitDecoratorMetadata": false,
    "experimentalDecorators": true,
    "esModuleInterop": true
  },
  "include": ["packages/**/*.ts"]
}

四、编写第一个组件

以 yc-button 为例:

TypeScript
// 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;
  }
}

导出组件入口:

TypeScript
// packages/yc-button/index.ts
export * from './src/YcButton.js';

五、自动化文档系统搭建

文档系统采用 11ty (Eleventy) 构建。
它是一款极轻量静态网站生成器,使用 Markdown + 模板语法快速生成静态页面,非常适合 Web Component 文档场景。

1. 安装依赖

Bash
npm install @11ty/eleventy @11ty/eleventy-plugin-syntaxhighlight

2. 创建 .eleventy.cjs 配置文件

JavaScript
// .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 中添加组件文档内容:

Markdown
---
title: YcButton 按钮组件
layout: base.njk
---

# `<yc-button>` 按钮组件

用于触发用户操作的基础按钮组件。

## 示例

```html
<yc-button label="点击我"></yc-button>

属性 (Props)

属性名类型默认值说明
labelstring'按钮'按钮文字

样式变量

变量名说明
--yc-btn-bg按钮背景色
--yc-btn-hover悬停背景色
JavaScript

其中 `<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。

安装与使用

Bash
npm install @custom-elements-manifest/analyzer --save-dev

在项目根目录添加 analyze.mjs:

JavaScript
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)
);

运行命令:

Bash
node analyze.mjs

生成后的 custom-elements.json 将被 Eleventy 文档系统读取并展示 API。


七、引入 Plop.js + AI 生成测试用例方案

在大型组件库中,重复编写单测文件成本高,因此引入 Plop.js 模板引擎 + AI 自动生成逻辑测试代码。

1. 安装依赖

Bash
npm install plop @types/node --save-dev

2. 新建 plopfile.cjs

JavaScript
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. 模板文件示例

TypeScript
// 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 行为,生成更多逻辑测试用例:

Bash
npx plop test

执行后输入组件名,如 yc-button,即可自动生成并补全测试文件内容。


八、构建与发布

构建组件库

使用 tsc 直接编译:

Bash
npx tsc

输出结果将包含 dist/ 目录内的所有 Web Components。

发布至 npm

Bash
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自动生成单测模板

🔗 参考资料

  • Lit 官方文档
  • 11ty 官方文档
  • Custom Elements Manifest
  • Plop.js 文档
标签: Eleventy Lit Plop.js Web Components
最后更新:2025年10月6日

cywcd

我始终相信,技术不仅是解决问题的工具,更是推动思维进化和创造价值的方式。从研发到架构,追求极致效能;在随笔中沉淀思考,于 AI 中对话未来。

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

cywcd

我始终相信,技术不仅是解决问题的工具,更是推动思维进化和创造价值的方式。从研发到架构,追求极致效能;在随笔中沉淀思考,于 AI 中对话未来。

最新 热点 随机
最新 热点 随机
深扒 Google Gemini Spark 这位"24小时不下班"的AI管家 Google推出Code Wiki,把“屎山代码”秒变可聊天的百科全书! VideoLingo凭什么敢称“全自动的视频本地化流水线”? 首个超2万亿级开源模型Kimi K3震撼发布,大模型格局彻底变天了? 别再手写 AI Agent 了!谷歌开源 agents-cli,一键给你的 AI 助手加满神仙级技能点 ChatGPT 实时语音 vs Gemini Live:深度实测!谁才是地表最强“无痛嘴替”?
开发者集体起立!cc-switch更新:原生干掉外挂,协议、会话、技能全包圆了!一键生成百万播放短视频?被吹上天的RedditVideoMakerBot,到底是搞钱神器还是时间杀手?别再迷信传统 RAG 了!知识库新物种 SAG 强势登场,实时干掉大模型“幻觉”!别再死磕提示词了!Google Flow Agent 彻底颠覆 AI 视频,有手就能当导演剪映要收网了?狂割韭菜后,这款狂揽5.7万Star的开源神器砸了谁的饭碗!被Figma卡脖子?这款自托管的开源神仙工具:Penpot,才是设计与开发的终极解药!
Claude Code最强国产平替来了,DeepSeek原生Agent省钱狂魔! 20 个现代 JavaScript API 深度盘点 WebAssembly(WASM)技术全景解析:从浏览器加速到云原生基石 剪映要收网了?狂割韭菜后,这款狂揽5.7万Star的开源神器砸了谁的饭碗! vue中使用v-for循环,动态绑定失效解决方法,循环列表显示/隐藏单独控制实例 vue3-touch-events:专为 Vue 3 设计的强大手势事件库
最近评论
渔夫 发布于 9 个月前(11月05日) 学到了,感谢博主分享
沙拉小王子 发布于 9 年前(11月30日) 适合vue入门者学习,赞一个
沙拉小王子 发布于 9 年前(11月30日) 适合vue入门者学习,赞一个
cywcd 发布于 9 年前(04月27日) 请参考一下这篇文章http://www.jianshu.com/p/fa4460e75cd8
cywcd 发布于 9 年前(04月27日) 请参考一下这篇文章http://www.jianshu.com/p/fa4460e75cd8

COPYRIGHT © 2025 蓝戒博客_智构苍穹-专注于大前端领域技术生态. ALL RIGHTS RESERVED.

京ICP备12026697号-2