rollup打包React组件库踩坑指南

2,538 阅读3分钟

之所以会有这次经历是因为在日常维护的项目中自己封装的UI组件多处使用,并且出现了跨项目的情况,所以就将该组件单独抽离出来变为一个npm包来维护

打包工具选择rollup是因为之前用它作为js的类库开发工具,做过react-hook相关的类库开发,至于优势更多的还是它基于es6模块规范打包 更易于做tree-shaking,配置简单吧

废话不多说,看一下这个过程中遇到了什么问题

#问题1

既然是开发组件库,少不了的就会有css文件的产生,所以就要有对应的插件去处理less(这是我用的预处理框架)文件, 最开始使用的是rollup-plugin-less, 一顿操作猛如虎,发现没办法定义输出css文件的路径???(也可能是因为我没找到),后来我又一想,postcss 还没有引入吧,于是就火速的安装了 rollup-plugin-postcss 这个插件,并进行了下边的配置

postcss({        
    plugins: [autoprefixer, cssnano],        
    extensions: ['.less', '.css'],        
    use: ['less'],        
    extract: 'multi-select.css', // 输出路径 
})

然后build查看结果。。然后就报错了

原因是因为rollup-plugin-postcss的版本过低的原因(库的框架建立出来有一段时间了,还没有来得及升级相关的依赖),这里的解决办法就是降级autoprefixer

由 "autoprefixer": "^10.x"  ->  "autoprefixer": "9.0.0",

同样的,cssnano 也存在版本过高的问题,由^5.0.0 -> 4.0.0

至此为止 less 文件可以被打包成css文件并正确的输出了

#问题2

UI组件里有时会用到一些图片,最好的处理办法就是转化为base64显示,这里就需要根据图片的大小来调整limit参数的大小

url({        
    limit: 20 * 1024, // inline files < 10k, copy files > 10k        
    // include: ["**/*.png"], // defaults to .svg, .png, .jpg and .gif files       
     // emitFiles: false // defaults to true
}),

#问题3

最后一个问题也是困扰了好久的问题,打包后的jsx文件里生成了一堆的辅助函数,这个很明显就是为了磨平不同浏览器之间的差异实现的polyfill,讲道理我已经在.babelrc中做了下边的配置

{    "presets": [      
        "@babel/preset-env",      
        "@babel/preset-react"    ],    
    "plugins": [      
        [        
        "@babel/plugin-transform-runtime",         
        {          
            "corejs": 3, // 指定 runtime-corejs 的版本,目前有 2 3 两个版本          
            "helpers": true        
        }      
        ],      
        "@babel/plugin-proposal-optional-chaining"    
    ]}

也就是使用了@babel/plugin-transform-runtime 插件来进行了转化,但是却没有在build后的文件首部看到从 "babel/runtime" 中导出的辅助函数,反而全部内联到了打包后的代码中。

一番搜索之后终于我在github中找到了答案

这个是 @rollup/plugin-babel的一个配置项,里边提到了必须要设置rollup的external过滤到"babel/runtime"这个关键词,否则就会得到内联在打包后的代码中的build文件。

于是 添加了下边这行配置到rollup.config.js中,再次打包发现问题解决了

external: id => id.includes('@babel/runtime'),

import _slicedToArray from '@babel/runtime-corejs3/helpers/slicedToArray';
import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes';
import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter';
import _concatInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/concat';
import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
import React, { useState, useMemo, useEffect } from 'react';import { Dropdown, Input, Button, Checkbox } from 'antd';
import { SearchOutlined, DownOutlined } from '@ant-design/icons';import cls from 'classnames';
import _defineProperty from '@babel/runtime-corejs3/helpers/defineProperty';
import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys';
import _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols';
import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor';
import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each';
import _Object$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors';
import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/object/define-properties';
import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property';

所有的辅助函数通过引入的方式传递了进来,最后附上github地址:

github.com/my-illusion…