Rollup打包React组件库并发布到npm私服

5,531 阅读4分钟

背景

公司的前端组件库经过前端好几位大佬搞了个基于React、Ant design二次扩展的库,之前设想是每个业务模块基于公共的组件库维护各自的业务组件库,经过几个周期之后,发现已经不可控了,每个业务模块的Ant design版本不一样,而且各自基于公共又搞了一套自己的库,为了收紧口子跟后期的维护扩展,决定把公共库打包发布到npm私服,然后install到各自业务线,确保各业务线一致,这是背景

打包

在这之前有使用rollup打包的经验,这里也计划用rollup来实现,这过程中碰到了不少问题,查阅相关资料发现国内基于Rollup打包React的比较少,所以基于这次经验想整理下,以便后续查阅,过程中遇到的相关问题如下:

  • 由于工程默认导出文件夹下的index.js文件,打包报错引入rollup-plugin-commonjs插件
  • React组件的"<"解析报错,引入@babel/preset-react解决
  • rollup.config.js plugins顺序不正确,先babel()再commjs(),不然commjs()打包报第2个错误
  • class组件中的属性报错,引入@babel/plugin-proposal-class-properties解决
  • class组件中的修饰符@打包报错,引入@babel/plugin-proposal-decorators解决,.babelrc 顺序必须在class-properties前
  • 代码中使用的新特性解析报错,引入@babel/preset-env解决
  • 使用rollup-plugin-less/rollup-plugin-less-modules打包出来引入的CSS文件不对,替换成rollup-plugin-postcss/rollup-plugin-less

启动

  • 运行打包文件报错,引入babel @babel/plugin-transform-runtime解决
  • 再运行,这个报错是因为 async/await 导致的,这个问题找了很久,最终在issues找到解决方案

第一个问题,回退到这个版本"@babel/plugin-transform-runtime": "7.1.0"/"@babel/runtime": "7.1.2"解决; 后面三个问题是ESLINT检查导致的,关闭ESLINT解决

  • 之前整个库之间有相互的引用,导致打包之后生成的index.js里面还有import库下的引用与绝对路径的引用,导致运行时无法找到引用的文件报错,rollup认为yss-biz是一个依赖,但是运行时实际并不存在,最后引入rollup-plugin-includepaths把yss-biz别名转成相对路径
  • uglif插件压缩报错,替换成rollup-plugin-terser解决

最后打包成功

  • Unused external imports 这个问题是因为import了uglify但是没用,忽略
  • Circular dependencies 因为历史原因,库中有使用yss-biz这个alias,后面通过rollup-plugin-includepaths重新定义这个别名的指向,最终出现循环引用,忽略
  • this has been rewritten to undefined 这是因为库中写的代码不正确用了箭头函数然后还绑定了this忽略
  • Unused external imports 这个是因为导入的内容没有使用,忽略

配置

rollup.config.js

import commonjs from "rollup-plugin-commonjs";
import babel from "rollup-plugin-babel";
import postcss from "rollup-plugin-postcss";
import ascii from "rollup-plugin-ascii";
import resolve from "@rollup/plugin-node-resolve";
import includePaths from "rollup-plugin-includepaths";
import { terser } from "rollup-plugin-terser";

const externalAry = [
  "antd",
  "antd/es/locale/zh_CN",
  "antd/dist/antd.css",
  "moment",
  "moment/locale/zh-cn",
  "echarts",
  "prop-types",
  "snowflake-id",
  "win-trade-base",
  "@lugia/lugiax",
  "@ant-design/icons",
  "react",
  "react-transition-group",
  "react-dnd",
  "react-dnd-html5-backend",
  "react-loadable",
  "react-resizable",
];

export default {
  input: "yss-biz-base/index.js",
  output: {
    file: "dist/index.js",
    format: "esm",
    sourcemap: true,
  },
  plugins: [
    resolve(),
    includePaths({
      include: { "yss-biz": "./yss-biz-base/index.js" },
    }),
    babel({ exclude: "**/node_modules/**", runtimeHelpers: true }),
    commonjs(),
    ascii(),
    postcss({
      // Extract CSS to the same location where JS file is generated but with .css extension.
      extract: true,
      // Use named exports alongside default export.
      namedExports: true,
      // Minimize CSS, boolean or options for cssnano.
      minimize: true,
      // Enable sourceMap.
      sourceMap: true,
      // This plugin will process files ending with these extensions and the extensions supported by custom loaders.
      extensions: [".less", ".css"],
    }),
    terser(),
  ],
  //不能使用正则匹配,有定制化组件也是以echarts命名
  external: externalAry,
};

package.json

  "dependencies": {
    "@babel/core": "^7.10.0",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-decorators": "^7.10.0",
    "@babel/plugin-syntax-jsx": "^7.8.3",
    "@babel/plugin-transform-react-jsx": "^7.9.4",
    "@babel/plugin-transform-runtime": "7.1.0",
    "@babel/preset-env": "^7.10.0",
    "@babel/preset-react": "^7.10.0",
    "@babel/runtime": "7.1.2",
    "@rollup/plugin-node-resolve": "^8.0.0",
    "rollup": "^2.10.9",
    "rollup-plugin-ascii": "^0.0.3",
    "rollup-plugin-babel": "^4.4.0",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-includepaths": "^0.2.3",
    "rollup-plugin-less": "^1.1.2",
    "rollup-plugin-postcss": "^3.1.1",
    "rollup-plugin-terser": "^6.1.0"
  },
  "devDependencies": {
    "colors": "^1.4.0",
    "inquirer": "^7.1.0"
  }

.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [
    "@babel/plugin-syntax-jsx",
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-react-jsx",
    "@babel/plugin-transform-runtime"
  ]
}

发布

发布到npm私服部分网站资料比较多,按照步骤来基本就没什么问题了

资料

www.bilibili.com/video/av893…

github.com/rollup/roll…

第一次记录写文章,文笔有限,多多包涵,ヾ(´ー`)ノ゛谢谢♪