React 组件库从 0 到发布完整流程(含文档)

1,503 阅读4分钟
  1. Dumi(文档、组件库开发)
  2. React + React Hook
  3. npm 组件库发布
  4. Github 静态发布
  5. Gitee 同步发布

源码地址: github.com/viewweiwu/t…

文档预览: viewweiwu.github.io/tomimi/

国内镜像: viewweiwu.gitee.io/tomimi/

1. 创建组件库

1.1 新建文件夹

tomimi 是指组件库名,可以自定义,之后所有的地方 tomimi 都是指组件库名。

#  此处的 tomimi 是指组件库名
mkdir tomimi && cd tomimi

1.2 导入组件库模板

npx @umijs/create-dumi-lib
# or
yarn create @umijs/dumi-lib

1.3 准备组件库 logo

添加组件库 logo,寻找一张大小差不多 100x100 的图片作为项目的 logo

存放到 /public/images/logo.png,没有目录则新建一个。

1.4 调整组件库文件

1.4.1 /.umirc.ts

import { defineConfig } from 'dumi';

export default defineConfig({
  title: 'tomimi',
  logo: '/tomimi/images/logo.png',
  outputPath: 'docs-dist',
  publicPath: '/tomimi/',
  base: '/tomimi/'
  // more config: https://d.umijs.org/config
});

1.4.2 /.fatherrc.ts

export default {
  entry: 'src/index.ts',
  esm: 'babel',
  cjs: 'babel'
};

1.4.3 /package.json

有注释的是需要调整的。

# 更换成新版本的 dumi
yarn add dumi@1.1.0-beta.25 -D
{
  // 组件库名,记得换成自己的
  "name": "tomimi",
  // 每次版本变更需要 +1
  "version": "0.0.4",
  "scripts": {
    "start": "dumi dev",
    "docs:build": "dumi build",
    "docs:deploy": "gh-pages -d docs-dist",
    "build": "father-build",
    "deploy": "npm run docs:build && npm run docs:deploy",
    "release": "npm run build && npm publish",
    "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"",
    "test": "umi-test",
    "test:coverage": "umi-test --coverage"
  },
  // 指定导出目录
  "files": [
    "es",
    "lib"
  ],
  // 入口换成 lib
  "main": "lib/index.js",
  // es 入口换成 es
  "module": "es/index.js",
  // 指定 TS 的,用于使用时的联想
  "typings": "lib/index.d.ts",
  // 指定证书
  "license": "MIT",
  "gitHooks": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*.{js,jsx,less,md,json}": [
      "prettier --write"
    ],
    "*.ts?(x)": [
      "prettier --parser=typescript --write"
    ]
  },
  "dependencies": {
    "react": "^16.12.0"
  },
  "devDependencies": {
    "@umijs/test": "^3.0.5",
    // 换成新版本
    "dumi": "^1.1.0-beta.25",
    "father-build": "^1.17.2",
    "gh-pages": "^3.0.0",
    "lint-staged": "^10.0.7",
    "prettier": "^1.19.1",
    "yorkie": "^2.0.0"
  }
}

2. 实现组件

2.1 创建文件

删除自带的 Foo 组件。

按照下面的目录来,没有则创建一个,如果有多余,则删除。

src
  TmButton // 按钮组件
    index.tsx // 组件入口
    tm-button.d.ts // TS 的各种 interface
    index.less // 样式
    index.d.ts // 组件联想
  index.d.ts // 组件库入口联想,只需要创建一次
  index.ts // 组件库入口,只需要创建一次

2.1.1 /src/TmButton/index.d.ts

指定组件需要的各种 interface。

import { ReactNode } from 'react'

export interface TmButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
  type?: 'primary' | 'error'
  children: ReactNode
  htmlType?: 'submit' | 'button' | 'reset'
  [key: string]: any
}

2.1.2 /src/TmButton/index.d.ts

指定 TS 入口。

import { TmButtonProps } from './tm-button'

declare const TmButton: React.ForwardRefExoticComponent<TmButtonProps & React.RefAttributes<HTMLDivElement>>

export default TmButton

2.1.3 /src/TmButton/index.tsx

编写按钮组件。

import React from 'react'
import './index.less'
import { TmButtonProps } from './tm-button'

export default function TmButton (props: TmButtonProps) {
  const { type, children, className, htmlType } = props
return <button {...props} className={`tm-button ${className} ${type || ''}`} type={htmlType}>{ children }</button>
}

2.1.4 /src/TmButton/index.less

编写按钮样式。

.tm-button {
  height: 32px;
  padding: 4px 15px;
  border: none;
  border-radius: 2px;
  font-size: 14px;
  color: #fff;
  background: linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;
  background-blend-mode: multiply, multiply;
  outline: none;
  cursor: pointer;

  &:hover {
    filter: brightness(1.2);
  }
  &:active {
    filter: brightness(0.8);
  }

  &.error {
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, rgb(204, 57, 57) 100%), radial-gradient(at top center, rgba(255, 255, 255, 0.4) 0%, rgb(255, 255, 255, 0.4) 120%) #ff8080;

    &:hover {
      filter: brightness(1.1);
    }
    &:active {
      filter: brightness(0.9);
    }
  }
}

2.1.5 /src/index.d.ts

编写组件 TS 入口。

export { default as TmButton } from './TmButton'

2.1.6 /src/index.ts

编写组件入口。

import TmButton from './TmButton'

export {
  TmButton
}

export default {
  TmButton
}

2.2 添加文档

2.2.1 /docs/TmButton.md

import { TmButton } from 'tomimi'

这种指定方式,引入 tomimi 的组件。

如果是开发模式,会引入 src 目录下的文件,修改下面的文件也会实时反应。

如果已经发布了,sandbox 示例会引入实际 npm 库。

  # TmButton

  ## 基础示例

  ```tsx
  import React from 'react'
  import { TmButton } from 'tomimi'

  export default function Demo() {
    return <TmButton>Tomimi</TmButton>
  }
  ```

  ## 所有状态

  ```tsx
  import React from 'react'
  import { TmButton } from 'tomimi'

  export default function Demo() {
    return (
      <>
        <TmButton type="primary" style={{ marginRight: 10 }}>Tomimi</TmButton>
        <TmButton type="error">Tomimi</TmButton>
      </>
    )
  }
  ```

2.2.2 /docs/index.md

此文件可以等待发布后再更新,一般是快速开始的一些引导。

# 快速开始

## 安装
```bash
npm i tomimi -S

yarn add tomimi -S
```

# 使用

```tsx
import React from 'react'
import { TmButton } from 'tomimi'

export default function Demo() {
  return <TmButton>Tomimi</TmButton>
}
```

2.3 预览

启动项目。

npm run start
# or
yarn start

3 发布

3.1 登录到 npm

没有 npm 账号的,到 官网 注册一个。

# 登录
npm login

3.2 发布到 npm

编译组件库。

npm run build
# or
yarn build

发布组件库。

npm publish .

发布完成后,会收到一封 npm 发布成功的邮件,同时在 npm 官网也可以查看到自己的组件库。

3.3 部署文档到 github

在 github 上创建空项目,名字为组件库名。

提交代码。

git init
# tomimi 为项目名,记得改
git remote add origin https://github.com/viewweiwu/tomimi.git
git branch -M main
git push -u origin main

编译文档到 gh-pages,它是 github 提供的静态服务。

npm run docs:build
# or
yarn docs:build

发布文档到 github。

npm run docs:deploy
# or
yarn docs:deploy

可以看到自己项目的地址。

滚动到下面,可以看到发布成功的地址。

viewweiwu.github.io/tomimi/

3.4 同步国内到 gitee

在 github 上找到自己的项目,复制 git 地址。

选择导入仓库,复制 URL,其它信息会自己同步的。

导入完成后,开启静态服务。

之后如果 github 导入后,只要点项目名字右边的刷新按钮,就会同步好了。

最后

整体流程: 创建组件库 》 实现组件库 》 发布组件库。