前期准备

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. 【CSP2019】【洛谷5657】格雷码

    传送门:https://www.luogu.com.cn/problem/P5657 题意不再复述: 我们知道对于每个字符1 or 0: 只要考虑当前的k在2^n的前半段还是后半段就行 这里需要注意的 ...

  2. BZOJ 3453 - tyvj 1858 XLkxc(插值+推式子)

    题面传送门 首先根据我们刚学插值时学的理论知识,\(f(i)\) 是关于 \(i\) 的 \(k+1\) 次多项式.而 \(g(x)\) 是 \(f(x)\) 的前缀和,根据有限微积分那一套理论,\( ...

  3. /etc/sudoers 文件

    sudo的权限控制可以在/etc/sudoers文件中查看到 如果想要控制某个用户(或某个组用户)只能执行root权限中的一部分命令, 或者允许某些用户使用sudo时不需要输入密码 格式一般都是 ro ...

  4. vector初始化的几种方式-STL

     vector<int>::iterator int_ite;  vector<string>::iterator string_ite;  //vector<T> ...

  5. 脱离Editor、VS等IDE如何编译UE4工程

    在Windows平台下,我们从.uproject文件生成VS解决方案.sln文件 .uproject文件用于打开Editor .sln文件用于打开VS工程 对于有增加C++代码的工程,Editor中和 ...

  6. 简单的Mybatis程序

    1.新建一个普通Maven项目,导入 mybatis.mysql.junit(用于测试)3个依赖 Mybatis <dependency> <groupId>org.mybat ...

  7. javascript的事件循环机制

    JavaScript是一门编程语言,既然是编程语言那么就会有执行时的逻辑先后顺序,那么对于JavaScript来说这额顺序是怎样的呢? 首先我们我们需要明确一点,JavaScript是单线程语言.所谓 ...

  8. day16 Linux三剑客之awk

    day16 Linux三剑客之awk 1.什么是awk,主要作用是什么? 什么是awk,主要作用是什么? awk 主要用来处理文件,将文本按照指定的格式输出.其中包含变量,循环以及数组. 2.awk的 ...

  9. Linux基础命令---htdigest建立和更新apache服务器摘要

    htdigest htdigest指令用来建立和更新apache服务器用于摘要认证的存放用户认证信息的文件. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.   1.语法   ...

  10. swagger文档

    关键配置文件 spring boot demo pom.xml <?xml version="1.0" encoding="UTF-8"?> < ...