前期准备

1. 初始化项目

npx create-react-app react-components --template typescript

2. 安装依赖

  • 使用哪种打包方案:webpack/rollup
**webpack**
* 代码分割:可以将打包后的代码分割成多个*.chunk.js,这些分块可以在用户使用过程中按需加载,这意味着用户可以有更好的交互体验。
* 静态资源导入:图片、CSS 等静态资源可以直接导入到你的 app 中,就和其它的模块、节点一样能够进行依赖管理。因此,我们再也不用小心翼翼地将各个静态文件放在特定的文件夹中,然后再去用脚本给文件 URL 加上哈希串了。
**rollup**
* Tree Shaking:这是rollup提出的一个特性,利用的es6模块的静态特性对导入的模块进行分析,只抽取使用到的方法,从而减小打包体积。
* 配置使用简便,生成的代码相对于Webpack更简洁。
* 可以指定生成生产中使用的各种不同的模块(amd,commonjs,es,umd)。
**异同**
* Webpack更适用于我们实际业务项目的打包,将代码和静态资源进行打包、分割、动态引入无需我们手动处理。
* rollup小巧使用配置方便可以对lib类库进行打包,代码运行效率更高。
* Webpack打包配置相对繁琐,打包出的代码体积相对较大,不同依赖之间执行会有依赖查找的情况,效率不如rollup。
* 简单来说:对于日常单页应用来说有代码和各种静态资源Webpack更适合,对于一些纯js/ts类库项目rollup更适合,rollup打包输入可以指定不同的格式(amd,commonjs,es,umd)应对各个场景引入使用。
  最终选定使用rollup进行打包,并安装rollup以及相关依赖
`yarn add -D rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-replace @rollup/plugin-image rollup-plugin-terser rollup-plugin-postcss postcss cssnano postcss-nested postcss-simple-vars` 安装好rollup后还需要配置babel,也需要安装babel配置需要的相关插件依赖
`yarn add -D @babel/cli @babel/core @babel/plugin-external-helpers @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread @babel/plugin-transform-react-jsx @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react @babel/preset-typescript`
  • storybook:用于组件库组件预览、组件测试和文档说明

    快速搭建 storybook react环境

    npx -p @storybook/cli sb init --type react

    Component Story Format (CSF,用于组件测试)

    为了支持typescript,还需要单独安装相关插件依赖

    yarn add -D @storybook/preset-create-react-app @storybook/react

  • eslint和prettier:用于规范代码

    代码检查借助Prettier以及ESLint的扩展,eslint-config-prettier将关闭所有不必要的或可能与Prettier冲突的规则。eslint-plugin-prettier则是添加Prettier格式设置规则的插件。

    yarn add -D eslint prettier eslint-config-prettier eslint-plugin-prettier eslint-plugin-react

  • husky和lint staged:用于规范commit

    Husky 与 Lint Staged来确保每次提交代码的正确性

    yarn add -D husky lint-staged

  • plop:用于组件模板创建

    With plop, you have your "best practice" method of creating any given pattern in CODE. Code that can easily be run from the terminal by typing plop. Not only does this save you from hunting around in your codebase for the right files to copy, but it also turns "the right way" into "the easiest way" to make new files.

    yarn add -D plop

3. 配置环境

  • 打包配置

    在根目录下创建rollup.config.js
// rollup.config.js
// Rollup plugins
// babel插件用于处理es6代码的转换,使转换出来的代码可以用于不支持es6的环境使用
import babel from 'rollup-plugin-babel';
// resolve将我们编写的源码与依赖的第三方库进行合并
import resolve from 'rollup-plugin-node-resolve';
// 解决rollup.js无法识别CommonJS模块
import commonjs from 'rollup-plugin-commonjs';
// 全局替换变量比如process.env
import replace from 'rollup-plugin-replace';
// 使rollup可以使用postCss处理样式文件less、css等
import postcss from 'rollup-plugin-postcss';
// 可以处理组件中import图片的方式,将图片转换成base64格式,但会增加打包体积,适用于小图标
import image from '@rollup/plugin-image';
// 压缩打包代码
import { terser } from 'rollup-plugin-terser';
// PostCSS plugins
// 处理css定义的变量
import simplevars from 'postcss-simple-vars';
// 处理less嵌套样式写法
import nested from 'postcss-nested';
// 可以提前适用最新css特性
import postcssPresetEnv from 'postcss-preset-env';
// css代码压缩
import cssnano from 'cssnano';
// 支持typescript
import typescript from 'rollup-plugin-typescript2';
// 用于打包生成*.d.ts文件
import dts from 'rollup-plugin-dts';
// 引入package
import pkg from './package.json'; const env = process.env.NODE_ENV; const config = [
{
// 入口文件我这里在components下统一导出所有自定义的组件
input: 'src/components/index.tsx',
// 输出文件夹,可以是个数组输出不同格式(umd,cjs,es...)通过env是否是生产环境打包来决定文件命名是否是.min
output: [
{
file: `dist/index.umd${env === 'production' ? '.min' : ''}.js`,
format: 'umd',
name: 'wcpnts',
},
{
file: `dist/index.esm${env === 'production' ? '.min' : ''}.js`,
format: 'esm',
},
{
file: `lib/index${env === 'production' ? '.min' : ''}.js`,
format: 'cjs',
},
],
// 注入全局变量比如jQuery的$这里只是尝试 并未启用
// globals: {
// react: 'React', // 这跟external 是配套使用的,指明global.React即是外部依赖react
// antd: 'antd'
// },
// 自定义警告事件,这里由于会报THIS_IS_UNDEFINED警告,这里手动过滤掉
onwarn: function (warning) {
if (warning.code === 'THIS_IS_UNDEFINED') {
return;
}
},
// 将模块视为外部模块,不会打包在库中
external: ['react', 'react-dom'],
// 插件
plugins: [
typescript(),
image(),
postcss({
plugins: [
simplevars(),
nested(),
// cssnext({ warnForDuplicates: false, }),
postcssPresetEnv(),
cssnano(),
],
// 处理.css和.less文件
extensions: ['.css', '.less'],
}),
// 告诉 Rollup 如何查找外部模块并安装它
resolve(),
// babel处理不包含node_modules文件的所有js
babel({
exclude: 'node_modules/**',
runtimeHelpers: true,
plugins: ['@babel/plugin-external-helpers'],
extensions: ['.js', '.ts', 'tsx'],
}),
// 将 CommonJS 转换成 ES2015 模块
// 这里有些引入使用某个库的api但报未导出该api通过namedExports来手动导出
commonjs({
namedExports: {
'node_modules/react-is/index.js': ['isFragment'],
'node_modules/react/index.js': [
'Fragment',
'cloneElement',
'isValidElement',
'Children',
'createContext',
'Component',
'useRef',
'useImperativeHandle',
'forwardRef',
'useState',
'useEffect',
'useMemo',
],
'node_modules/react-dom/index.js': [
'render',
'unmountComponentAtNode',
'findDOMNode',
],
'node_modules/gojs/release/go.js': [
'Diagram',
'GraphLinksModel',
'Overview',
'Spot',
],
},
}),
// 全局替换NODE_ENV,exclude表示不包含某些文件夹下的文件
replace({
// exclude: 'node_modules/**',
'process.env.NODE_ENV': JSON.stringify(env || 'development'),
}),
// 生产环境执行terser压缩代码
env === 'production' && terser(),
],
},
{
// 入口文件我这里在components下统一导出所有自定义的组件
input: 'src/components/index.tsx',
// 输出文件夹,可以是个数组输出不同格式(umd,cjs,es...)通过env是否是生产环境打包来决定文件命名是否是.min
output: [
{
file: `${pkg.types}`,
format: 'esm',
},
],
plugins: [
dts(),
postcss({
plugins: [
simplevars(),
nested(),
// cssnext({ warnForDuplicates: false, }),
postcssPresetEnv(),
cssnano(),
],
// 处理.css和.less文件
extensions: ['.css', '.less'],
}),
],
},
]; export default config;
  在package.json中添加一下代码
{
"main": "lib/index.js",
"module": "dist/index.esm.js",
"browser": "dist/index.umd.js",
"types": "lib/index.d.ts",
"scripts": {
"rollup-build": "cross-env BABEL_ENV=rollup rollup -c",
"rollup-production-build": "cross-env NODE_ENV=production rollup -c",
},
"files": [
"dist",
"lib"
],
}
  • storybook配置

    安装成功后,会自动在package.json 中添加下面语句:
"scripts": {
...
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
}
  为了支持tsx文件,需要在.storybook/main.js中增加配置项和根据自己项目进行部分调整(.storybook目录是运行完storybook init后自动创建出来的)
module.exports = {
"stories": [
"../src/stories/*.stories.mdx",
"../src/stories/*.stories.tsx"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/preset-create-react-app", // 用来支持tsx文件
]
}
  • eslint配置
  • prettier配置
  • husky配置:在package.json 中添加下面语句:
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
  • lint staged配置:在package.json 中添加下面语句:
"lint-staged": {
"src/**/*.{css,scss,less,json,html,md,markdown}": [
"prettier --write",
"git add"
],
"src/**/*.{js,jsx,mjs,ts,tsx}": [
"prettier --write",
"eslint --fix",
"git add"
]
}
  • plop配置:创建plopfile.js,并创建模板文件(模板文件和要生成的文件路由和名字都可以自定义)
module.exports = function (plop) {
// create your generators here
plop.setGenerator('basics', {
description: 'this is a component',
prompts: [ // 提示问题,可以是多问题,以数组的形式表示
{ // 可以根据输入的name动态创建组件的相关文件
type: 'input',
name: 'name',
message: 'please input component name',
},
],
actions: [ // 命令完成对应的操作,可以是多操作,以数组的形式表示
{
type: 'add', // 创建文件
path: 'src/components/{{name}}/index.tsx', // 生成的文件
templateFile: 'templates/index.tsx', // 模板文件
},
{
type: 'add',
path: 'src/components/{{name}}/index.less',
templateFile: 'templates/index.less',
},
{
type: 'add',
path: 'src/stories/{{name}}.stories.tsx',
templateFile: 'templates/index.stories.tsx',
},
],
});
};
  • 我的模板文件

  • 执行plop命令的过程,根据提示问题输入组件名称Modal

  • 命令执行完成后,plop会自动创建在配置中设定好的目录

组件开发

1. 组件设计思路及规范

  • 初始化组件:创建组件模板plop
  • 打包版本号升级

2. 项目目录设计

所有组件都放到components下,每个组件一个文件夹,首字母大写,在components下创建一个index.tsx文件,用于导出所有组件

3. 组件编写

PR 标题规则:[ bug fix / breaking change / new feature ] 组件名字:修改内容描述

前面方括号用来区分 PR / issue 的类型:bug fix - 组件 bug 修复;breaking change - 不兼容的改动;new feature - 新功能

修改内容尽可能言简意赅,总结 PR 的改动或者描述 issue

描述请用中文

组件名字请用英文,首字母大写

4. 组件测试

组件维护

1. 组件发布

// 将npm源设置为你自己私有库的地址
npm config set registry ****
// 登录npm私有库,根据提示输入用户名、密码、邮箱,如果没有账号需要先在私有库上添加账号
npm login
// 发布包到自己的私有库上
npm publish

2. 组件说明文档

完善CHANGELOG.md

3. 组件变更记录

安装conventional-changelog-cli和cz-conventional-changelog依赖,可以根据commit的信息自动生成CHANGELOG.md

在package.json中添加以下配置

"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
},

遇到的问题

运行storybook时样式文件没有生效

TODO

发布storybook,支持组件在线预览

使用react搭建组件库:react+typescript+storybook的更多相关文章

  1. beeshell —— 开源的 React Native 组件库

    介绍 beeshell 是一个 React Native 应用的基础组件库,基于 0.53.3 版本,提供一整套开箱即用的高质量组件,包含 JavaScript(以下简称 JS)组件和复合组件(包含 ...

  2. react_app 项目开发 (4)_ React UI 组件库 ant-design 的基本使用

    最流行的开源 React UI 组件库 material-ui 国外流行(安卓手机的界面效果)文档 ant-design 国内流行 (蚂蚁金服 设计,一套 PC.一套移动端的____下拉菜单.分页.. ...

  3. Vitepress搭建组件库文档(上)—— 基本配置

    在 vite 出现以前,vuepress 是搭建组件库文档不错的工具,支持以 Markdown 方式编写文档.伴随着 vite 的发展,vitepress 已经到了 1.0.0-alpha.22 版本 ...

  4. Vitepress搭建组件库文档(下)—— 组件 Demo

    上文 <Vitepress搭建组件库文档(上)-- 基本配置>已经讨论了 vitepress 搭建组件库文档的基本配置,包括站点 Logo.名称.首页 home 布局.顶部导航.左侧导航等 ...

  5. Vue3 企业级优雅实战 - 组件库框架 - 3 搭建组件库开发环境

    前文已经初始化了 workspace-root,从本文开始就需要依次搭建组件库.example.文档.cli.本文内容是搭建 组件库的开发环境. 1 packages 目录 前面在项目根目录下创建了 ...

  6. 从零搭建react+ts组件库(封装antd)

    为什么会有这样一篇文章?因为网上的教程/示例只说了怎么做,没有系统详细的介绍引入这些依赖.为什么要这样配置,甚至有些文章还是错的!迫于技术洁癖,我希望更多的开发小伙伴能够真正的理解一个项目搭建各个方面 ...

  7. React UI 组件库uiw v1.2.8 发布

    uiw 高品质的UI工具包,基于React 16+的组件库.

  8. 从零开始封装React UI 组件库并发布到NPM

    github 开源地址:zswui github 说明文档:wiki 1.新建目录wui (1)进入到 wui 目录 执行 npm init 命令初始化项目.更具提示信息填充将会生成的 package ...

  9. react/redux组件库、模板、学习教程

    开源的有蚂蚁金服的: 1.https://pro.ant.design/index-cn 2.https://pro.ant.design/docs/getting-started-cn 3.http ...

随机推荐

  1. CF1418G Three Occurrences

    统计满足某些性质的区间个数. 我们考虑移动 \(r\) 指针. 然后考虑把不能选的区间 \(ban\)掉. 具体看下细节吧. #include<iostream> #include< ...

  2. Atcoder Grand Contest 022 E - Median Replace(dp)

    Atcoder 题面传送门 & 洛谷题面传送门 首先考虑对于固定的 01 串怎样计算它是否可以通过将三个连续的 \(0\) 或 \(1\) 替换为其中位数得到.我们考虑单调栈,新建一个栈,栈底 ...

  3. windows系统开/关机日志位置

    邮件计算机=>管理 =>系统工具=>事件查看器=>Windows日志=>系统 过滤:关机:事件ID=6006 开机:事件ID=6005

  4. 《python编程从入门到实践》读书实践笔记(二)

    本文是<python编程从入门到实践>读书实践笔记11章的内容,主要包含测试,为体现测试的重要性,独立成文. 11 测试代码 写在前面的话,以下是我这些年开发中和测试相关的血泪史. 对于一 ...

  5. [linux] mv: cannot move $ to $: Directory not empty

    最近测试某流程时,跑的过程报错了,于是检查脚本修改后重新测试.脚本是改过来了,但在shell中运行某步时碰到了如题报错! $ mv MP_genus_network_files/ tax_networ ...

  6. Django结合Echarts在前端展示数据

    前言 最近在用Django写UI自动化测试平台,基本快要弄完了,但是首页只有项目列表展示,一直感觉很空旷,所以想把一些关键数据在首页展示出来. 这时就想到利用Echarts这个开源项目,但是Djang ...

  7. PC端页面转换成手机端页面的分辨率问题的理解

    PC端页面转换成手机端页面的分辨率问题的理解 px vw rem 假如就以a4纸模式为设计图 ,在a3纸模式中设计,然后设计出来展示在不同的a4纸模式上 通常是 750px -> 100vw / ...

  8. MapReduce08 数据清洗(ETL)和压缩

    目录 数据清洗(ETL) ETL清洗案例 需求 需求分析 实现代码 编写WebLogMapper类 编写WebLogDriver类 打包到集群运行 压缩 概念 MR支持的压缩编码 压缩算法对比 压缩性 ...

  9. day08 索引的创建与慢查询优化

    day08 索引的创建与慢查询优化 昨日内容回顾 视图 视图:将SQL语句查询结果实体化保存起来,方便下次查询使用. 视图里面的数据来源于原表,视图只有表结构 # 创建视图 create view 视 ...

  10. centos7安装Docker详细步骤(无坑版教程)

    一.安装前必读 在安装 Docker 之前,先说一下配置,我这里是Centos7 Linux 内核:官方建议 3.10 以上,3.8以上貌似也可. 注意:本文的命令使用的是 root 用户登录执行,不 ...