使用rollup + react + typescript开发一个组件库

如题,大家在日常开发中针对可复用的ui及逻辑,都会在项目中封装组件,以达到复用的目的。目前市面上也有很多优秀的ui组件库,像antd、vant等,这些框架也给我们日常开发提供了很多的便利,本文使用react框架 搭配rollup来分享一下,如何开发维护一个我们自己的组件库。

技术选型

编译工具

目前市面上的构建工具主要有webpack、vite、rollup以及gulp,rollup总能打出更小体积的包,vite本身也是集成rollup,之后添加更多的功能及插件,但是组件库相对来说不是很需要,所以这里使用rollup进行编译。

文档工具

目前主要使用的是两个,一个是 storybook,现在github star数量是80.8k ,使用更广泛。另外一个是 Dumi和father-build,目前star数量是3.3k,但是阿里出品,中文文档方便一些。这两者都可以自动生成文档,极大提高项目可维护性,这里选用storybook。

包管理工具

这里使用yarn,npm的包管理相对混乱,pnpm在实际使用中,发现安装存在一定问题,经常丢包,所以这里使用yarn作为包管理工具

框架

使用react@18.2进行开发,css预编译工具为scss,typescript版本为@5.2.2,大家可以结合自己的情况自由选择,编译库所用工具为rollup,storybook预览组件项目库时,使用webpack进行编译,node版本为18.17.0,eslint + prettierrc进行代码检测,项目最终目录结构为

lua 复制代码
.
|-- package.json
|-- public
|   |-- favicon.ico
|   |-- index.html
|   |-- logo192.png
|   |-- logo512.png
|   |-- manifest.json
|   `-- robots.txt
|-- readme.md
|-- rollup.config.mjs
|-- src
|   |-- Introduction.stories.mdx
|   |-- assets
|   |   |-- close.svg
|   |   |-- phone.svg
|   |   `-- verify.svg
|   |-- components
|   |   |-- login
|   |   |   |-- AtLogin.tsx
|   |   |   |-- index.scss
|   |   |   |-- login.stories.mdx
|   |   |   |-- login.stories.tsx
|   |   |   `-- index.tsx
|   |   |-- login-popup
|   |   |   |-- AtLoginPopup.tsx
|   |   |   |-- index.scss
|   |   |   |-- index.ts
|   |   |   |-- loginPopup.stories.mdx
|   |   |   |-- loginPopup.stories.tsx
|   |   |   `-- show.tsx
|   |   `-- button
|   |       |-- Button.stories.mdx
|   |       |-- Button.tsx
|   |       `-- index.ts
|   |-- demo
|   |   `-- login
|   |       `-- index.tsx
|   |-- global
|   |   |-- global.scss
|   |   |-- index.ts
|   |   |-- theme-dark.scss
|   |   `-- theme-default.scss
|   |-- index.ts
|   |-- react-app-env.d.ts
|   |-- type.d.ts
|   `-- utils
|       |-- attach-properties-to-component.ts
|       |-- axios.ts
|       |-- index.ts
|       |-- native-props.ts
|       |-- render-imperatively.tsx
|       `-- renderToBody.tsx
|-- tsconfig.json
|-- yarn-error.log
`-- yarn.lock

基础架构搭建

快速开始

使用create-react-app创建一个初始项目,执行命令:

lua 复制代码
npx create-react-app my-component --template typescript

接入storybook

使用storybook,如果你不熟悉storybook,请前往storybook学习了解。

bash 复制代码
cd ./my-component
npx storybook init

执行完成后,此时在项目根目录下执行:

arduino 复制代码
yarn run storybook

将在本地启动 Storybook 并输出地址。

新增组件

在src目录下创建components,并在components目录下,创建button文件夹,添加文件如下图:

其中index.ts文件主要处理一些导入导出及其他必要的公共逻辑,组件文件为Button.tsx,为单纯的组件:

Button.stories.mdx 为文档文件,语法几乎等同markdown语法,如图,可从storybook中导出三个组件

  • Meta // 用于生成文档菜单
  • Story // 用于渲染真正的业务组件
  • Canvas // 用于渲染story组件

在上图中,<Canvas>组件包裹的部分,会在页面真正渲染。

如需进一步完善文档,可在同级目录中添加 stories.tsx 文件,通过增减配置,可以生成可编辑的预览页面,配置可参考如下:

编译

使用rollup进行编译,配合terser进行混淆压缩,以降低代码体积,具体配置可参考如下:

上图中,箭头所指的地方可以实时进行修改,页面实时预览

javascript 复制代码
/* eslint-disable import/no-unresolved */
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import strip from '@rollup/plugin-strip';
import typescript from '@rollup/plugin-typescript';
import autoprefixer from 'autoprefixer';
import path from 'path';
import externals from 'rollup-plugin-node-externals';
import postcss from 'rollup-plugin-postcss';
import json from '@rollup/plugin-json';
import pluginUrl from '@rollup/plugin-url';
import terser from '@rollup/plugin-terser';

import pkg from './package.json' assert { type: 'json' };

export default [
  {
    input: './src/index.ts',
    output: [{
      dir: path.dirname(pkg.module),
      format: 'es',
      name: pkg.name,
      exports: 'named', // 指定导出模式(自动、默认、命名、无)
      preserveModules: true, // 保留模块结构
      preserveModulesRoot: 'src', // 将保留的模块放在根级别的此路径下
    }],
    plugins: [
      externals({
        devDeps: false,
      }),
      json(),
      resolve(),
      pluginUrl(),
      commonjs(),
      typescript({
        outDir: 'es',
        declaration: true,
        declarationDir: 'es',
        tsconfig: 'tsconfig.json',
      }),
      postcss({
        plugins: [
          autoprefixer(),
        ],
      }),
      terser(), // 压缩
      strip(),
    ],
  },
];

编译后即可得到制品,再方式npm或者私有源即可

相关推荐
Qrun10 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp10 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.1 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front7 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰8 小时前
纯flex布局来写瀑布流
前端·javascript·css