库打包工具 Rollup
1. rollup核心思想和场景
1.1 认识rollup
-
看一下官方对rollup的定义:
- Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application.
- Rollup是一个JavaScript的模块化打包工具,可以帮助我们编译小的代码到一个大的、复杂的代码中,比如一个库或者一个应用程序
-
Rollup的定义、定位和webpack非常的相似:
- Rollup也是一个模块化的打包工具,但是Rollup主要是针对ES Module进行打包的
- 另外webpack通常可以通过各种loader处理各种各样的文件,以及处理它们的依赖关系
- rollup更多时候是专注于处理JavaScript代码的(当然也可以处理css、font、vue等文件)
- rollup的配置和理念相对于webpack来说,更加的简洁和容易理解
- 在早期webpack不支持tree shaking时,rollup具备更强的优势
1.2 应用场景
-
目前webpack和rollup分别应用在什么场景呢?
- 通常在实际项目开发过程中,都会使用webpack(比如react、angular项目都是基于webpack的)
- 在对库文件进行打包时,通常会使用rollup(比如vue、react、dayjs源码本身都是基于rollup的,Vite底层使用Rollup)
2. rollup命令行打包
- 不同的执行环境使用不同命令
# 打包浏览器的库 npx rollup ./src/main.js -f iife -o dist/bundle.js # 打包AMD的库 npx rollup ./src/main.js -f amd -o dist/bundle.js # 打包CommonJS的库 node环境 npx rollup ./src/main.js -f cjs -o dist/bundle.js # 打包通用的库(必须跟上name) npx rollup ./src/main.js -f umd --name mathUtil -o dist/bundle.js
3. rollup配置文件编写
-
将配置信息写到配置文件中rollup.config.js文件
module.exports = { // 入口 input: './lib/index.js', // 出口 // output: { // format: 'umd', // name: 'ysUtils', // file: './build/bundle.umd.js' // } // 打包不同格式 output: [ { format: 'umd', name: 'ysUtils', file: './build/bundle.umd.js' }, { format: 'amd', file: './build/bundle.amd.js' }, { format: 'cjs', file: './build/bundle.cjs.js' }, { format: 'iife', name: 'ysUtils', file: './build/bundle.browser.js' } ] }
-
打包文件
- 执行脚本:
npx rollup -c
- 执行脚本:
4. rollup打包第三方库
-
解决commonjs的问题
- 默认lodash没有被打包是因为它使用commonjs, rollup默认情况下只会处理es module
- 解决commonjs导出,es module导入
npm install @rollup/plugin-commonjs -D
-
解决node_modules的问题
rollup
并不支持直接打包node-modules
里面的内容,所以需要安装rollup-plugin-node-resolve
插件npm install @rollup/plugin-node-resolve -D
-
配置文件
const commonjs = require('@rollup/plugin-commonjs') const nodeResolve = require('@rollup/plugin-node-resolve') module.exports = { // 入口 input: './lib/index.js', // 出口 output: { format: 'umd', name: 'ysUtils', file: './build/bundle.umd.js', globals: { lodash: '_' } }, external: ['lodash'], plugins: [ commonjs(), nodeResolve(), ] }
5. rollup打包js文件
-
babel转换代码
- babel.config.js配置文件
npm install @rollup/plugin-babel -D
-
terser压缩代码
npm install @rollup/plugin-terser -D
-
配置文件
const commonjs = require('@rollup/plugin-commonjs') const nodeResolve = require('@rollup/plugin-node-resolve') // 代码转换和压缩 const { babel } = require('@rollup/plugin-babel') const terser = require('@rollup/plugin-terser') module.exports = { // 入口 input: './lib/index.js', // 出口 output: { format: 'umd', name: 'ysUtils', file: './build/bundle.umd.js', globals: { lodash: '_' } }, external: ['lodash'], plugins: [ commonjs(), nodeResolve(), babel({ // polyfill babelHelpers: 'bundled', exclude: /node_modules/ }), terser() ] }
6. rollup处理css文件
-
处理css文件,可以使用postcss
npm install rollup-plugin-postcss postcss -D
npm install postcss-preset-env -D
-
配置文件
const commonjs = require('@rollup/plugin-commonjs') const nodeResolve = require('@rollup/plugin-node-resolve') // 代码转换和压缩 const { babel } = require('@rollup/plugin-babel') const terser = require('@rollup/plugin-terser') const html = require('@rollup/plugin-html') const postcss = require('rollup-plugin-postcss') module.exports = { // 入口 input: './src/index.js', // 出口 output: { format: 'umd', name: 'ysUtils', file: './build/bundle.umd.js', globals: { lodash: '_' } }, // external: ['lodash'], plugins: [ commonjs(), nodeResolve(), babel({ // polyfill babelHelpers: 'bundled', exclude: /node_modules/ }), terser(), html(), postcss({ plugins: [require('postcss-preset-env')]}), ] }
7. rollup处理vue文件
-
处理vue文件需要使用rollup-plugin-vue插件:
npm install rollup-plugin-vue @vue/compiler-sfc -D
-
打包后vue项目会报错
- 因为在打包的vue代码中,用到
process.env.NODE_ENV
,所以可以使用一个插件 rollup-plugin-replace 设置它对应的值:npm install @rollup/plugin-replace -D
- 因为在打包的vue代码中,用到
-
注意:插件有先后顺序,
vue()
放到postcss()
前面,否则后面修改css内容会报错 -
配置文件
const commonjs = require('@rollup/plugin-commonjs') const nodeResolve = require('@rollup/plugin-node-resolve') // 代码转换和压缩 const { babel } = require('@rollup/plugin-babel') const terser = require('@rollup/plugin-terser') const html = require('@rollup/plugin-html') const postcss = require('rollup-plugin-postcss') const vue = require('rollup-plugin-vue') // 注入变量 const replace = require('rollup-plugin-replace') module.exports = { // ... plugins: [ vue(), commonjs(), nodeResolve(), babel({ // polyfill babelHelpers: 'bundled', exclude: /node_modules/ }), terser(), html(), postcss({ plugins: [require('postcss-preset-env')]}), replace({ 'process.env.NODE_ENV': JSON.stringify('production') }) ] }
8. rollup搭建本地服务器
-
第一步:使用rollup-plugin-serve搭建服务
npm install rollup-plugin-serve -D
-
第二步:当文件发生变化时,自动刷新浏览器
npm install rollup-plugin-livereload -D
-
第三步:启动时,开启文件监听
npx rollup -c -w
-
配置文件
const commonjs = require('@rollup/plugin-commonjs') const nodeResolve = require('@rollup/plugin-node-resolve') // 代码转换和压缩 const { babel } = require('@rollup/plugin-babel') const terser = require('@rollup/plugin-terser') const html = require('@rollup/plugin-html') const postcss = require('rollup-plugin-postcss') const vue = require('rollup-plugin-vue') // 注入变量 const replace = require('@rollup/plugin-replace') const serve = require('rollup-plugin-serve') const livereload = require('rollup-plugin-livereload') module.exports = { // ... plugins: [ commonjs(), nodeResolve(), babel({ // polyfill babelHelpers: 'bundled', exclude: /node_modules/ }), terser(), html(), vue(), // postcss({ plugins: [require('postcss-preset-env')]}), postcss(), replace({ 'process.env.NODE_ENV': JSON.stringify('production'), preventAssignment: true }), serve({ port: 8080, // open: true, // 依赖的文件夹 contentBase: './build' }), livereload() ] }
9. rollup区分不同环境
- 在package.json中创建脚本
"scripts": { "build": "rollup -c --environment NODE_ENV:production", "serve": "rollup -c --environment NODE_ENV:development -w" },
- 配置文件
const commonjs = require('@rollup/plugin-commonjs') const nodeResolve = require('@rollup/plugin-node-resolve') // 代码转换和压缩 const { babel } = require('@rollup/plugin-babel') const terser = require('@rollup/plugin-terser') const html = require('@rollup/plugin-html') const postcss = require('rollup-plugin-postcss') const vue = require('rollup-plugin-vue') // 注入变量 const replace = require('@rollup/plugin-replace') const serve = require('rollup-plugin-serve') const livereload = require('rollup-plugin-livereload') const isProduction = process.env.NODE_ENV === 'production' const plugins = [ commonjs(), nodeResolve(), babel({ // polyfill babelHelpers: 'bundled', exclude: /node_modules/ }), html(), vue(), // postcss({ plugins: [require('postcss-preset-env')]}), postcss(), replace({ 'process.env.NODE_ENV': JSON.stringify('production'), preventAssignment: true }) ] if(isProduction) { plugins.push(terser()) } else { const extraPlugins = [ serve({ port: 8080, // open: true, contentBase: './build' }), livereload() ] plugins.push(...extraPlugins) } module.exports = { // 入口 input: './src/index.js', // 出口 output: { format: 'umd', name: 'ysUtils', file: './build/bundle.umd.js', globals: { lodash: '_' } }, // external: ['lodash'], plugins: plugins }
转载自:https://juejin.cn/post/7181629432644239416