Open wbccb opened 1 year ago
本文基于rollup 3.20.2进行分析,作为后续想要使用rollup打包库(包含公共组件库)的参考资料 注:每隔一段时间会进行实时更新
本文基于rollup 3.20.2进行分析,作为后续想要使用rollup打包库(包含公共组件库)的参考资料
rollup 3.20.2
rollup
注:每隔一段时间会进行实时更新
Rollup 是 JavaScript 的模块打包器,它可以将小块代码编译成更大更复杂的东西,例如库或应用程序。 它使用 JavaScript ES6 修订版中包含的代码模块的新标准化格式,而不是以前的特殊解决方案,如 CommonJS 和 AMD。 ES 模块让您可以自由无缝地组合您最喜欢的库中最有用的单个函数。 这最终将在任何地方成为可能,但 Rollup 现在可以让你做到这一点。
Rollup 可以通过插件导入现有的 CommonJS 模块。
如果你想使用 require 和 module.exports 将配置编写为 CommonJS 模块,你应该将文件扩展名更改为 .cjs。
在根目录使用rollup.config.js或者rollup.config.mjs进行配置
rollup.config.js
rollup.config.mjs
入口文件地址
output: { file: './dist/my-lib.js' // 输出文件 format: 'umd' // 输出格式: cjs, umd, iife, es6, amd name: 'myLib', //当format为iife和umd时必须提供,将作为全局变量挂在window(浏览器环境)下:window.myLib=... sourcemap: true // 生成源码映射文件 }
// rollup typescript配置处理 `@rollup/plugin-typescript` /* * 帮助寻找node_modules里的包 * rollup.js编译源码中的模块引用默认只支持ES6+的模块方式import/export。 * 然而大量的npm模块是基于CommonJS模块方式,这就导致了大量 npm 模块不能直接编译使用。 * 所以辅助rollup.js编译支持npm模块和CommonJS模块方式的插件就应运而生 */ `@rollup/plugin-node-resolve` // 支持import 'xx.json'文件 `@rollup/plugin-json` // 在打包的时候把目标字符串替换å `@rollup/plugin-replace` // 对打包的js进行压缩 `rollup-plugin-terser` // 删除原来的bundle `rollup-plugin-delete` // 显示打包后文件的大小 `rollup-plugin-filesize` // 将CommonJs语法转成es5 `@rollup/plugin-commonjs` // rollup 的 babel 插件,ES6转ES5 `rollup-plugin-babel`
告诉rollup不要把第三方库进行打包,而是作为外部依赖, 配合”peerDependencies“使用, 这样业务代码引入我们的公共库的时候避免了重复下载
// 第三方esm 语法的包 const external = [/lodash-es\/[a-z]+/, 'ts-date', 'classnames'] // 第三方cjs 语法的包 const cjsExteranl = ['classnames']
告诉rollup,全局变量React就是react
globals: { 'react': 'React', 'react-dom': 'ReactDOM' }
安装插件
rollup-plugin-babel
@babel/core
@babel/preset-env
//rollup.dev.js import babel from 'rollup-plugin-babel' export default { input: ..., output: ..., plugins:[ babel({ exclude: 'node_modules/**' }) ] }
babel需要作如下配置:
比如创建.babelrc配置文件 { "presets": [ [ "@babel/preset-env", { // 设置为false, 否则babel会在rollup有机会执行其操作之前导致我们的模块转化为commonjs "modules": false, // polyfill按需引入 "useBuiltIns": "usage", "corejs": 3 } ], "@babel/preset-react" ] }
比如创建.babelrc配置文件
.babelrc
{ "presets": [ [ "@babel/preset-env", { // 设置为false, 否则babel会在rollup有机会执行其操作之前导致我们的模块转化为commonjs "modules": false, // polyfill按需引入 "useBuiltIns": "usage", "corejs": 3 } ], "@babel/preset-react" ] }
typescript
@rollup/plugin-typescript
tslib
import typescript from '@rollup/plugin-typescript' const plugins = [ typescript({ declaration: false }) ].filter(Boolean)
rollup-plugin-postcss
autoprefixer
cssnano
browserslist
注意也要安装postcss依赖,即npm i postcss --D
postcss
npm i postcss --D
rollup-plugin-postcss可配置是否将css单独分离,默认没有extract,css样式生成style标签内联到head中,配置了extract,就会将css抽离成单独的文件。
extract
style
import postcss from 'rollup-plugin-postcss' import autoprefixer from 'autoprefixer' import cssnano from 'cssnano' export default { plugins:[ postcss({ plugins: [ autoprefixer(), cssnano ] }) ] }
使用.browserslist文件或者在package.json中配置browserslist字段
.browserslist
package.json
"browserslist": [ "defaults", "not ie < 8", "last 2 versions", "> 1%", "iOS 7", "last 3 iOS versions" ]
安装插件@rollup/plugin-commonjs
@rollup/plugin-commonjs
import commonjs from '@rollup/plugin-commonjs' export default { plugins:[ commonjs() ] }
安装插件rollup-plugin-vue、@vue/compiler-sfc
rollup-plugin-vue
@vue/compiler-sfc
rollup-plugin-vue也是默认支持scss、less、stylus,可以在项目中直接使用。给.vue文件中的css自动加前缀,需要在rollup-plugin-vue中配置。 import vue from 'rollup-plugin-vue' import autoprefixer from 'autoprefixer' import cssnano from 'cssnano' export default { plugins:[ vue({ style: { postcssPlugins: [ autoprefixer(), cssnano() ] } }) ] }
rollup-plugin-vue也是默认支持scss、less、stylus,可以在项目中直接使用。给.vue文件中的css自动加前缀,需要在rollup-plugin-vue中配置。
scss
less
stylus
.vue
import vue from 'rollup-plugin-vue' import autoprefixer from 'autoprefixer' import cssnano from 'cssnano' export default { plugins:[ vue({ style: { postcssPlugins: [ autoprefixer(), cssnano() ] } }) ] }
安装插件rollup-plugin-terser
rollup-plugin-terser
import { terser } from 'rollup-plugin-terser' export default { plugins:[ terser() ] }
安装插件rollup-plugin-serve、rollup-plugin-livereload
rollup-plugin-serve
rollup-plugin-livereload
import serve from 'rollup-plugin-serve' import livereload from 'rollup-plugin-livereload' export default { plugins:[ serve({ contentBase: '', //服务器启动的文件夹,默认是项目根目录,需要在该文件下创建index.html port: 8020 //端口号,默认10001 }), livereload('dist') //watch dist目录,当目录中的文件发生变化时,刷新页面 ] }
//package.json "scripts": { "dev": "rollup --watch" },
Rollup 提供了可在 Node.js 中使用的 JavaScript API。一般情况下不需要使用它,而应使用命令行 API,除非你要扩展 Rollup 本身或者使用它进行一些高级操作,比如通过编程生成 bundle。
rollup.rollup 函数接收输入选项对象作为参数,并返回一个 Promise,该 Promise 解析为具有各种属性和方法的 bundle 对象,如下所示。 在此步骤中,Rollup 将构建模块图并执行 tree-shaking,但不会生成任何输出。
在 bundle 对象上,您可以使用不同的输出选项对象多次调用 bundle.generate,以在内存中生成不同的 bundle。 如果直接将它们写入磁盘,请改用 bundle.write。
const rollup = require('rollup'); // 有关选项的详细信息,请参见下文 const inputOptions = {...}; const outputOptions = {...}; async function build() { // 创建一个 bundle const bundle = await rollup.rollup(inputOptions); console.log(bundle.watchFiles); // 该 bundle 依赖的文件名数组 // 在内存中生成输出特定的代码 // 您可以在同一个 bundle 对象上多次调用此函数 const { output } = await bundle.generate(outputOptions); for (const chunkOrAsset of output) { if (chunkOrAsset.type === 'asset') { // 对于assets,包含 // { // fileName: string, // asset 文件名 // source: string | Uint8Array // asset 资源 // type: 'asset' // 表示这是一个 asset // } console.log('Asset', chunkOrAsset); } else { // 对于chunks, 包含 // { // code: string, // 生成的JS代码 // dynamicImports: string[], // chunk 动态导入的外部模块 // exports: string[], // 导出的变量名 // facadeModuleId: string | null, // 该chunk对应的模块的ID // fileName: string, // chunk的文件名 // imports: string[], // chunk 静态导入的外部模块 // isDynamicEntry: boolean, // 该 chunk 是否是动态入口点 // isEntry: boolean, // 该 chunk 是否是静态入口点 // map: string | null, // sourcemaps(如果存在) // modules: { // 此 chunk 中模块的信息 // [id: string]: { // renderedExports: string[]; // 导出的已包含变量名 // removedExports: string[]; // 导出的已删除变量名 // renderedLength: number; // 模块中剩余代码的长度 // originalLength: number; // 模块中代码的原始长度 // }; // }, // name: string // 命名模式中使用的 chunk 的名称 // type: 'chunk', // 表示这是一个chunk // } console.log('Chunk', chunkOrAsset.modules); } } // 或者将bundle写入磁盘 await bundle.write(outputOptions); } build();
const inputOptions = { // 核心输入选项 external, input, // 必选 plugins, // 高级输入选项 cache, onwarn, preserveEntrySignatures, strictDeprecations, // 危险选项 acorn, acornInjectPlugins, context, moduleContext, preserveSymlinks, shimMissingExports, treeshake, // 实验型选项 experimentalCacheExpiry, perf };
const outputOptions = { // 核心输出选项 dir, file, format, // 必选 globals, name, plugins, // 高级输出选项 assetFileNames, banner, chunkFileNames, compact, entryFileNames, extend, externalLiveBindings, footer, hoistTransitiveImports, inlineDynamicImports, interop, intro, manualChunks, minifyInternalExports, outro, paths, preserveModules, sourcemap, sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, // 危险选项 amd, esModule, exports, freeze, indent, namespaceToStringTag, noConflict, preferConst, strict, systemNullSetters };
Rollup 也提供了 rollup.watch 函数,当它检测到磁盘上单个模块已经改变,它会重新构建你的 bundle。 当你通过命令行运行 Rollup,并带上 "--watch" 标记时,它将在内部使用。
const rollup = require('rollup'); const watchOptions = {...}; const watcher = rollup.watch(watchOptions); watcher.on('event', event => { // event.code 会是下面其中一个: // START — 监听器正在启动(重启) // BUNDLE_START — 构建单个 bundle // BUNDLE_END — 完成 bundle 构建 // END — 完成所有bundle构建 // ERROR — 构建时遇到错误 }); // 停止监听 watcher.close();
Rollup是什么
Rollup 是 JavaScript 的模块打包器,它可以将小块代码编译成更大更复杂的东西,例如库或应用程序。 它使用 JavaScript ES6 修订版中包含的代码模块的新标准化格式,而不是以前的特殊解决方案,如 CommonJS 和 AMD。 ES 模块让您可以自由无缝地组合您最喜欢的库中最有用的单个函数。 这最终将在任何地方成为可能,但 Rollup 现在可以让你做到这一点。
CommonJS
Rollup 可以通过插件导入现有的 CommonJS 模块。
配置文件
在根目录使用
rollup.config.js
或者rollup.config.mjs
进行配置基础配置
input
入口文件地址
output
基础plugins
external
告诉rollup不要把第三方库进行打包,而是作为外部依赖, 配合”peerDependencies“使用, 这样业务代码引入我们的公共库的时候避免了重复下载
global
告诉rollup,全局变量React就是react
其它配置
转化es6语法配置
安装插件
rollup-plugin-babel
@babel/core
@babel/preset-env
babel需要作如下配置:
typescript配置
安装插件
typescript
@rollup/plugin-typescript
tslib
CSS配置
rollup-plugin-postcss
、autoprefixer
(前缀)、cssnano
(压缩),支持css文件的加载、css加前缀、css压缩、对scss/less的支持等等。browserslist
rollup.config.js
browserslist
使用
.browserslist
文件或者在package.json
中配置browserslist
字段CommandJS
安装插件
@rollup/plugin-commonjs
Vue
安装插件
rollup-plugin-vue
、@vue/compiler-sfc
代码压缩
安装插件
rollup-plugin-terser
开发环境调试代码
安装插件
rollup-plugin-serve
、rollup-plugin-livereload
使用Javascript API进行自定义高级打包
Rollup 提供了可在 Node.js 中使用的 JavaScript API。一般情况下不需要使用它,而应使用命令行 API,除非你要扩展 Rollup 本身或者使用它进行一些高级操作,比如通过编程生成 bundle。
rollup.rollup
rollup.rollup 函数接收输入选项对象作为参数,并返回一个 Promise,该 Promise 解析为具有各种属性和方法的 bundle 对象,如下所示。 在此步骤中,Rollup 将构建模块图并执行 tree-shaking,但不会生成任何输出。
在 bundle 对象上,您可以使用不同的输出选项对象多次调用 bundle.generate,以在内存中生成不同的 bundle。 如果直接将它们写入磁盘,请改用 bundle.write。
inputOptions
outputOptions
rollup.watch
Rollup 也提供了 rollup.watch 函数,当它检测到磁盘上单个模块已经改变,它会重新构建你的 bundle。 当你通过命令行运行 Rollup,并带上 "--watch" 标记时,它将在内部使用。
参考