从0搭建自己的UI组件库文档平台

3,244 阅读4分钟

背景

目前部门内部正在推动工程化建设与技术栈迁移(Preact->React),因此许多旧项目就需要进行重构,原本封装的各种UI组件也都是依赖于Preact框架,且都是单独的npm包形式存在,代码风格各异,没有一个统一的UI组件查询平台,基于此,我们决定建设一个统一的UI组件库。

目标

  • 组件可视化(支持多平台H5/PC)

  • 自动生成API文档,较少的书写文档工作量

组件文档方案调研

  1. React Docgen

官方介绍:

react-docgen 是一个 CLI 和工具箱,可帮助从 React 组件中提取信息并从中生成文档。它使用 AST 类型和@babel/parser 将源解析为 AST,并提供处理此 AST 的方法以提取所需的信息。输出/返回值是一个 JSON blob/JavaScript 对象。

也就是说它能够提取组件的一些关键信息,我们再根据这些信息转化为 markdown,最后依据这些 markdown 生成组件说明文档。没有组件预览,且额外工作量较多,pass

  1. docz

这是一个基于 MDX 文件生成组件文档的库,你可以在每个组件内部自动添加 mdx 文件, Docz 会自动将其转化部署生成文档库。仍然需要自己书写 mdx 文件,pass

  1. Storybook

  2. React Styleguidist

Storybook(star: 57.2k) 与 Styleguidist(React-Styleguidist star: 9.5k) 都是很完备的组件文档自动生成方案,支持组件预览与组件交互状态展示等,支持组件 API 文档自动生成。同时,Storybook 相对于 Styleguidist 还有以下优点:

  1. 支持移动端预览
  2. 支持更多框架更丰富(React/Vue/Angular/Web Component/Ember/HTML/Mithril/Marko/Svelte/Riot/Preact/Rax/RN等)

设计开发

  1. 首先在项目中安装 storybook 依赖,如下为我们项目中安装的 storybook 相关依赖与插件, storybook 提供了一个丰富的插件市场,可以丰富组件库平台功能。
"devDependencies": {
  "@storybook/addon-actions": "^6.0.28",
  "@storybook/addon-console": "^1.2.2",
  "@storybook/addon-essentials": "^6.0.28",
  "@storybook/addon-links": "^6.0.28",
  "@storybook/addons": "^6.0.28",
  "@storybook/react": "^6.0.28",
  "@storybook/theming": "^6.0.28",
}
  1. 安装 storybook 后项目中会增加一个 .storybook 的文件夹,里边包含了一些 storybook 的基本配置
// main.js storybook 打包构建配置文件
module.exports = {
  // 需要打包构建生成文档文件所在文件夹
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  // 需要启用的第三方 addons
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  // storybook 已经包含一份基本的 webpack 配置,同时支持自定义配置项
  webpackFinal: async (config) => {
    config.devtool = false;
    config.performance = {
      hints: false,
      maxEntrypointSize: 512000,
      maxAssetSize: 512000,
    };
    return config;
  },
};


// manager.js 组件库基本主题样式配置文件
import { addons } from '@storybook/addons';
import { create } from '@storybook/theming';

addons.setConfig({
  showRoots: true,
  theme: create({
    base: 'light',
    brandUrl: '***',
    // brandImage: 'https://y.qq.com/favicon.ico',
    brandTitle: 'QQ音乐UI组件库',
  }),
});

  1. 组件开发与文档生成

组件目录结构

.
├── Avatar.stories.tsx
├── index.tsx
└── style
    └── index.css

组件入口文件 index.tsx

import * as React from 'react';
import { fixUrl } from '../libs/pic';

// 组件 Props 定义,storybook 会据此生成 API 说明文档(支持PropsType)
export interface IAvatarProps {
  /**
   * 头像尺寸       // 该字段用于描述组件参数 Description
   */
  size: number;
  /**
   * 头像链接
   */
  avatarUrl: string;
  /**
   * alt属性
   */
  altName?: string;
}

/**
 * 这里还可以添加组件自定义说明
 *
 */
export const Avatar: React.FunctionComponent<IAvatarProps> = (props) => {
  const { size = Avatar.defaultProps.size, avatarUrl, altName = Avatar.defaultProps.altName } = props;
  return (
    <img
      style={{ display: 'block', width: size, height: size, borderRadius: size }}
      src={fixUrl(avatarUrl)}
      alt={altName || '用户头像'}
    />
  );
};

// 组件默认参数
Avatar.defaultProps = {
  size: 100,
  altName: '头像',
};


storybook 文件 A.ctories.tsx

import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';
import { IAvatarProps, Avatar } from './index';

// 定义组件分组/tab名称
export default {
  title: '数据展示/Avatar 头像',
  component: Avatar,
  argTypes: {},
} as Meta;

// 组件预览 Demo,支持多个 demo 预览
const Template: Story<IAvatarProps> = (args) => <Avatar {...args} />;

export const 头像 = Template.bind({});
头像.args = {
  size: 100,
  avatarUrl: 'https://y.gtimg.cn/music/photo_new/T001R150x150M000002lO5Lc1GCmvn_2.jpg',
  altName: 'nickName',
};


  1. 执行 yarn run storybook 直接在浏览器预览效果,切换到 canvas 标签栏,可以直接修改组件参数,组件预览会实时更新。

image1

imagw2

image3

  1. 添加组件库使用说明文档,支持 MDX 文档
// index.stories.mdx
import { Meta } from '@storybook/addon-docs/blocks';

// 分组名称信息设置
<Meta title="介绍/Getting started" />

# Getting Started

## 使用

以`Input`组件为例说明


import { Input } from '***';
  1. 文档打包发布

运行 yarn run build-storybook 会在根目录生成 storybook-static 文档产物,直接发布构建产物即可。