跳转到内容

工具与生态集成 ​

Lit 与现代 Web 开发工具链良好集成,支持 TypeScript、各种构建工具和开发工具。

TypeScript 支持 ​

Lit 官方提供完整的 TypeScript 支持,包括类型定义和装饰器:

typescript
import { LitElement, html, css, PropertyValues } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';

@customElement('my-element')
export class MyElement extends LitElement {
  @property({ type: String })
  name: string = 'World';

  @state()
  private _count: number = 0;

  static styles = css`
    :host {
      display: block;
    }
  `;

  render() {
    return html`<p>Hello, ${this.name}! Count: ${this._count}</p>`;
  }

  protected firstUpdated(_changedProperties: PropertyValues) {
    super.firstUpdated(_changedProperties);
    // 在这里可以安全地访问 DOM
  }
}

TypeScript 配置 ​

推荐的 tsconfig.json 配置:

json
{
  "compilerOptions": {
    "target": "es2021",
    "module": "es2020",
    "lib": ["es2021", "DOM", "DOM.Iterable"],
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "inlineSources": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "useDefineForClassFields": false
  },
  "include": ["src/**/*.ts"],
  "exclude": []
}

构建工具集成 ​

Vite ​

Vite 是开发 Lit 组件的优秀选择:

js
// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    lib: {
      entry: 'src/my-element.js',
      formats: ['es'],
    },
    rollupOptions: {
      external: /^lit/,
    },
  },
});

Webpack ​

使用 Webpack 配置 Lit 项目:

js
// webpack.config.js
module.exports = {
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },
  output: {
    filename: 'bundle.js',
    path: __dirname + '/dist',
  },
};

Rollup ​

使用 Rollup 构建 Lit 组件:

js
// rollup.config.js
import nodeResolve from '@rollup/plugin-node-resolve';
import babel from '@rollup/plugin-babel';

export default {
  input: 'src/index.js',
  output: {
    dir: 'dist',
    format: 'es',
  },
  plugins: [
    nodeResolve(),
    babel({
      babelHelpers: 'bundled',
      presets: [
        ['@babel/preset-env', {
          targets: {
            esmodules: true,
          },
        }],
      ],
    }),
  ],
  external: ['lit'],
};

开发工具集成 ​

Storybook ​

为 Lit 组件配置 Storybook:

js
// .storybook/main.js
module.exports = {
  stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: ['@storybook/addon-essentials'],
  framework: '@storybook/web-components',
};
js
// my-element.stories.js
import { html } from 'lit';
import './my-element.js';

export default {
  title: 'My Element',
  component: 'my-element',
};

export const Basic = () => html`<my-element></my-element>`;

export const WithName = () => html`<my-element name="Storybook"></my-element>`;

ESLint ​

配置 ESLint 进行代码检查:

js
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  env: {
    browser: true,
    es2021: true,
  },
  rules: {
    // 自定义规则
  },
};

Playwright ​

使用 Playwright 进行端到端测试:

typescript
// my-element.test.ts
import { test, expect } from '@playwright/test';

test('should update count on button click', async ({ page }) => {
  await page.goto('/my-element');
  
  const button = await page.locator('my-element button');
  await button.click();
  
  await expect(page.locator('my-element span')).toHaveText('1');
});

Jest ​

使用 Jest 进行单元测试:

typescript
// my-element.test.ts
import { fixture, html } from '@open-wc/testing';
import './my-element.js';

describe('MyElement', () => {
  it('should render correctly', async () => {
    const el = await fixture(html`<my-element></my-element>`);
    expect(el).shadowDom.to.equal('<p>Hello, World!</p>');
  });

  it('should update name property', async () => {
    const el = await fixture(html`<my-element name="Test"></my-element>`);
    expect(el.shadowRoot?.textContent).to.include('Hello, Test!');
  });
});

调试工具 ​

浏览器 DevTools ​

Lit 组件与浏览器开发者工具完全兼容:

  1. 可以在 Elements 面板中检查 Shadow DOM
  2. 在 Console 中直接访问组件属性和方法
  3. 使用 Performance 面板分析渲染性能
js
// 在浏览器控制台中调试
const element = document.querySelector('my-element');
console.log(element.name); // 访问属性
element.name = 'New Name'; // 修改属性
element.requestUpdate(); // 请求更新

Lit DevTools ​

Lit DevTools 是专门为 Lit 开发的 Chrome 扩展:

  1. 显示组件树和属性
  2. 检查组件状态和属性
  3. 调试渲染更新

包管理 ​

npm ​

发布 Lit 组件到 npm:

json
{
  "name": "my-lit-component",
  "version": "1.0.0",
  "type": "module",
  "main": "index.js",
  "module": "index.js",
  "exports": {
    ".": "./index.js"
  },
  "files": [
    "index.js",
    "src/"
  ],
  "peerDependencies": {
    "lit": "^2.0.0"
  }
}

发布脚本 ​

package.json 中的构建和发布脚本:

json
{
  "scripts": {
    "build": "rollup -c",
    "dev": "vite",
    "test": "npm run test:unit && npm run test:e2e",
    "test:unit": "jest",
    "test:e2e": "playwright test",
    "lint": "eslint src/**/*.ts",
    "prepublishOnly": "npm run build"
  }
}

生态系统 ​

官方库 ​

  1. @lit/reactive-element - Lit 的核心响应式基础库
  2. lit-html - Lit 的模板系统
  3. @lit/localize - 国际化支持
  4. @lit-labs - 实验性功能和库

社区库 ​

  1. @open-wc - Web Component 开发工具集
  2. lit-analyzer - Lit 组件的静态分析工具
  3. @vaadin/component-base - Vaadin 组件基础库

设计系统 ​

许多设计系统基于 Lit 构建:

  1. Material Web (Material Design Components)
  2. Shoelace
  3. Vaadin Components
  4. Lion Web Components

最佳实践 ​

  1. 使用 TypeScript 获得更好的开发体验
  2. 配置适当的构建工具以优化生产环境性能
  3. 使用 Storybook 等工具进行组件开发和文档编写
  4. 实施自动化测试确保组件质量
  5. 使用 ESLint 等工具保持代码质量
  6. 利用浏览器 DevTools 进行调试
  7. 跟踪 Lit 生态系统的新工具和最佳实践