前期准备

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. C/C++ Qt TableDelegate 自定义代理组件

    TableDelegate 自定义代理组件的主要作用是对原有表格进行调整,例如默认情况下Table中的缺省代理就是一个编辑框,我们只能够在编辑框内输入数据,而有时我们想选择数据而不是输入,此时就需要重 ...

  2. 详解Threejs中的光源对象

    光源的分类 AmbientLight(环境光),PointLight(点光源),SpotLight(聚光源) 和 DirectionalLight(平行光)是基础光源 HemisphereLight( ...

  3. Codeforces 1332G - No Monotone Triples(数据结构综合)

    Codeforces 题目传送门 & 洛谷题目传送门 首先打表即可发现对于任意长度 \(\ge 5\) 的序列总存在一个 Monotone triple,证明不会实在不行直接 \(5^5\) ...

  4. Linux终端命令行的快捷键列表

    tab键:命令.文件名等自动补全功能. Ctrl+a:光标回到命令行首.Ctrl+e:光标回到命令行尾.Ctrl+k:删除光标处到行尾的字符.Ctrl+u:删除整个命令行文本字符.ctrl+y: 粘贴 ...

  5. 浅谈Facebook的服务器架构

    导读:毫无疑问,作为全球最领先的社交网络,Facebook的高性能集群系统承担了海量数据的处理,它的服务器架构一直为业界众人所关注.CSDN博主yanghehong在他自己最新的一篇博客< Fa ...

  6. 浅讲.Net 6 之 WebApplicationBuilder

    介绍 .Net 6为我们带来的一种全新的引导程序启动的方式.与之前的拆分成Program.cs和Startup不同,整个引导启动代码都在Program.cs中. WebApplicationBuild ...

  7. 同步阻塞IO模型

    同步阻塞IO模型 有上篇IO模型中的,同步阻塞IO模型,我们能够知道,用户线程发起请求后就一直阻塞的等待 内核完成准备数据.数据拷贝的工作.并且返回成功的指示. 实现 使用java来实现同步阻塞IO模 ...

  8. MediaPlayer详解

    [1]MediaPlayer 详细使用细则 [2]MediaPlayer使用详解_为新手准备 [3]MediaPlayer 概览

  9. Git配置文件与git config命令

    在Git配置文件中配置变量,可以控制Git的外观和操作的各个方面.通过git config命令可以获得和设置配置变量. 一.Git配置文件的位置 这些变量可以被存储在三个不同的位置: 1./etc/g ...

  10. C++ 害死人不偿命的(3n+1)猜想

    第一次刷PAT ,注意事项:就像普通编译器一样要导入头文件 还有 using namespace std:要不然会报错(鬼知道我经历了什么 微笑.jpg) 1 #include <iostrea ...