基于rollup+typescript+gulp+less搭建react前端组件库。输出esm,umd,cjs三种格式,支持服务端渲染,cmd引入以及es6规范。使用rollup编译输出格式(方便好用代码比webpack干净点),gulp做构建,考虑到三种规范又需要支持服务端渲染。
cjs与es规范的组件我们需要按照编码的文件结构输出,如编码src/components/button组件,那么输出es,cjs规范文件结构就应该是es/components/button及cjs/components/button。cjs,es规范我们还要考虑对服务端渲染的支持。我们知道服务端渲染只关心html片段,并不关心样式,样式都是在浏览器注入渲染完成。那么我们编写组件的时候就要考虑不导入样式了。那么不导入样式我们又怎么在开发的时候以及生产环境使用的时候让样式生效呢。聪明的朋友其实已经想到我们可以解析语法树然后主动注入一行代码进入导入样式。那么我们就可以使用babel编写一个插件,使用babel解析语法树动态去注入脚本代码,比如给你的组件脚本注入import './index.less';这样的代码。没错这就是antd design的babel-import-plugin插件干的事情。我们将使用这个插件做一样的处理,如果想自己造一个babel插件的朋友也可以查看babel官方文档或者查看我另外一片文章如何编写babel插件。对于umd我们要考虑浏览器直接使用cnd的方式需要将样式与脚本打包到一个文件中方便导入。
基于上面的缘由我们考虑我们要编译生成的文件结构需要什么样子,会使用什么工具。

文档工具(dumi)

本来想直接使用dumi做组件库的编译,但是我用dumi实验了一下发现问题有点多,可能是使用方式不对,于是直接用rollup重新配置了一套,dumi只是做文档工具

构建工具

构建工具使用gulp(构建上比webpack好用太多)。首先package.json中,script字段添加一个脚本命令用于gulp构建启动入口build:component,如下:

{
"scripts": {
    "start": "dumi dev",
    "build": "npm run docs:build",
    "docs:build": "dumi build",
    "docs:deploy": "gh-pages -d docs-dist",
    "build:component": "gulp",
  },
}

build:component。启动gulp命令新版本gulp会自动去寻找gulpfile.js这个文件然后执行里面的index脚本,注意gulpfile.js是一个文件名,不是一个js脚本,详细情况还是取看看gulp官方文档JavaScript 和 Gulpfile

最终编译出的目录结构

上面已经提到我们最终要输出三种规范的代码,es,cjs,umd。那么我们将这三种规范分别输出到根目录dist目录下的es,cjs,dist三个目录下边。同时规范下的组件输出目录和源码组件编写目录保持一致:如下:
规范输出文件

下面是组件输出目录(以es规范为例,cjs一致,dist用于cdn会打包到一个js文件中)

上面说到我们不会在组件中导入样式为了支持服务端渲染,我们要用到babel-import-plugin在使用组件库的时候主动去配置导入规则。那么我们需要将样式生成规则统一方便导入,这里我们将在所有组件下面单独生成一个style文件去存放样式然后使用babel-import-plugin去注入这样子一行代码import './style/index';所以我们组件的编写方式和生成格式就如下图:
以写的checkbox组件为例,这是源码文件结构

可以看到源码的style文件就是用来存储checkbox组件的样式,那么下面有一个index脚本是导出所有样式文件的出口

这是输出的es规范目录结构,cjs类似

可以看到我们输出了两种类型的文件css和less(这样两种输出是通过gulp完成的后面会讲)是因为我们要支持css的使用以及less预编译的使用。我们还生成了index.js脚本以及css.js脚本。index脚本是作为less使用者的入口,css.js作为css使用的入口.
css入口

less入口

使用css的时候我们就使用babel-import-plugin配置编译给后checkbox的入口文件注入import './style/css';这样子的代码.使用less的时候我们配置编译后注入import './style/index';这样子的代码。
那么在服务端渲染的时候我们不需要关心样式我们只需要生成html片段,不使用babel-import-plugin即可,那么浏览器cdn导入的时候我们可以从umd规范中去导入整个样式包,也就是输出目录下面的dist目录:

ti.css中就包含了所有的组件样式

关于主题定制

主题定制我采用的方式是使用less的变量覆盖我们将所有可变的变量定义在一个文件中


color文件

less的变量覆盖,在使用库的时候可以虽然去覆盖同名变量

这一章我们先说实现目标,下一章基于rollup+typescript+gulp+less搭建react 前端组件库(二)我们将开始将如何实现。(不对之处请指出)

03-05 15:48