官网
https://github.com/rollup/rollup
英文文档
中文文档
是什么
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。
使用
新建文件夹nodejslibstu02
,执行如下命令
pnpm init
pnpm add -D rollup
新建rollup.config.mjs
export default {input: 'src/index.js',output: {file: 'dist/bundle.js',format: 'iife',//iife下需要指定namename: 'bundle',},
};
src下新建foo.js
export default 'hello world!';
src下新建index.js
import foo from './foo.js';
export default function () {console.log(foo);
}
修改package.json
"type": "module",
"scripts": {"build": "rollup --config"
},
执行pnpm run build
,打包结果如下
这个代码是直接可以在js中使用的
常用参数
input
该选项用于指定 bundle 的入口文件(例如,你的 main.js,app.js 或 index.js 文件)。如果值为一个入口文件的数组或一个将名称映射到入口文件的对象,那么它们将被打包到单独的输出 chunks。除非使用 output.file 选项,否则生成的 chunk 名称将遵循 output.entryFileNames 选项设置。当该选项的值为对象形式时,对象的属性名将作为文件名中的 [name],而对于值为数组形式,数组的值将作为入口文件名。
string | string[] | { [entryAlias: string]: string }
input: 'src/index.js',
input: ['src/index.js','src/index2.js'],
output
输出结果配置
MaybePromise<OutputPlugin | NullValue | false | OutputPluginOption[]>
output:{file:'bundle.js', // 输出文件format: 'cjs, // 6种输出格式:amd / es6 / iife / umd / cjs / systemname:'A', //当format为iife和umd时必须提供,将作为全局变量挂在window(浏览器环境)下:window.A=...sourcemap:true //生成bundle.map.js文件,方便调试
}
plugins
各种插件使用的配置
MaybePromise<Plugin | NullValue | false | InputPluginOption[]>
plugins: [resolve(),commonjs(),isProduction && (await import('@rollup/plugin-terser')).default()
],
external
该选项用于匹配需要排除在 bundle 外部的模块,它的值可以是一个接收模块 id 参数并返回 true (表示外部依赖)或 false (表示非外部依赖)的函数,也可以是一个模块 ID 数组或者正则表达式。除此之外,它还可以只是单个的模块 ID 或正则表达式。被匹配的模块 ID 应该满足以下条件之一:
- 外部依赖的名称,需要和引入语句中写法完全一致。例如,如果想标记 import “dependency.js” 为外部依赖,就需要使用 “dependency.js” 作为模块 ID;而如果要标记 import “dependency” 为外部依赖,则使用 “dependency”。
- 解析过的模块 ID(如文件的绝对路径)。
(string | RegExp)[]| RegExp| string| (id: string, parentId: string, isResolved: boolean) => boolean
external:['lodash'] //告诉rollup不要将此lodash打包,而作为外部依赖
global
该选项用于在 umd / iife bundle 中,使用 id: variableName 键值对指定外部依赖。
{ [name: string]: string } | ((name: string) => string)
例如,在这样的情况下
import $ from 'jquery';//我们需要告诉 Rollup jquery 是外部依赖,jquery 模块的 ID 为全局变量 $// rollup.config.mjs
export default {external: ['jquery'],output: {format: 'iife',name: 'MyBundle',globals: {jquery: '$'}}
};
CommonJS:适用于Node.js环境的输出,使用CommonJS模块化规范。简称
cjs
ES Module:可以在现代浏览器端及Node.js中使用的输出,使用ESM模块化规范。简称es
UMD:兼容浏览器端及Node.js环境的输出,可以通过script标签导入,同时也支持CommonJS和AMD规范。通用模块定义规范,同时支持 amd,cjs 和 iife,简称umd
AMD:适用于使用AMD规范载入模块的环境,比如require.js。简称amd
SystemJS:适用于使用SystemJS载入模块的环境,比如jspm。简称system
iife:普通的全局变量方式导出,适合浏览器端,可以通过script标签导入。简称iife
插件
https://github.com/rollup/plugins/tree/master
创建压缩文件
安装插件
pnpm add -D @rollup/plugin-terser
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';export default {input: 'src/index.js',output: [{file: 'dist/bundle.js',format: 'iife',name: 'bundle',sourcemap: true,},{file: 'dist/bundle.min.js',format: 'iife',name: 'bundle',plugins: [terser()]}],
};
执行打包命令,如果放在最外层的plugins目录下就是都压缩
找到外部模块打包
@rollup/plugin-node-resolve
插件可以让 Rollup 找到外部模块,在 node_modules 中查找并捆绑第三方依赖项
pnpm add -D @rollup/plugin-node-resolve
安装一个jquery
pnpm add -D jquery
修改index.js
import foo from './foo.js';
import jQuery from 'jquery';function testJquery(){jQuery(function (){console.log('juqery加载完成')})
}
testJquery();
export default function () {console.log(foo);
}
修改rollup.config.mjs
//import resolve from '@rollup/plugin-node-resolve';
import { nodeResolve } from '@rollup/plugin-node-resolve';export default {// 其他省略//plugins:[resolve()]plugins:[nodeResolve()]
};
如果配有配置plugins打包还是原来的大小只有自己写的代码,配置好resolve插件之后打包如下
由于 node_modules 文件夹中的大多数软件包可能是传统的 CommonJS 而非 JavaScript 模块,因此可能需要使用 @rollup/plugin-commonjs:
pnpm add -D @rollup/plugin-commonjs
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';export default {input: 'src/index.js',output: [{file: 'dist/bundle.js',format: 'umd',name: 'bundle',sourcemap: true,},{file: 'dist/bundle.min.js',format: 'umd',name: 'bundle',plugins: [terser()]}],plugins:[nodeResolve(),commonjs()]
};
打包成功体积变大了
请注意,大多数情况下,@rollup/plugin-commonjs 应该放在转换模块的其他插件之前 - 这是为了防止其他插件对 CommonJS 检测产生影响。一个例外是 Babel 插件,如果你使用它,请将它放在 commonjs 插件之前。
代码分割
代码分割是指有些情况下 Rollup 会自动将代码拆分成块,例如动态加载或多个入口点,还有一种方法可以显式地告诉 Rollup 将哪些模块拆分成单独的块,这是通过 output.manualChunks 选项实现的。
要使用代码分割功能实现惰性动态加载(其中某些导入的模块仅在执行函数后加载),我们返回到原始示例,并修改 src/main.js,以动态加载 src/foo.js 而不是静态加载:
修改index.js
// export default function () {
// console.log(foo);
// }
//上面代码是原来的
export default function () {import('./foo.js').then(({ default: foo }) => console.log(foo));
}
UMD and IIFE不支持分包打包,所以需要修改为cjs,然后不能使用file,而是使用dir,修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';export default {input: 'src/index.js',output: [{format: 'cjs',name: 'bundle',sourcemap: true,dir: 'dist/bundle',}],plugins:[terser(),nodeResolve(),commonjs()]
};
src下新建index2.js
export default function () {import('./foo.js').then(({ default: foo }) => console.log(foo));
}
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';export default {input: ['src/index.js',"src/index2.js"],output: [{format: 'cjs',name: 'bundle',sourcemap: true,dir: 'dist/bundle',}],plugins:[terser(),nodeResolve(),commonjs()]
};
只生成了一个foo
Babel
为了正确解析我们的模块并使其与旧版浏览器兼容,我们应该包括babel来编译输出。许多开发人员在他们的项目中使用 Babel ,以便他们可以使用未被浏览器和 Node.js 支持的将来版本的 JavaScript 特性。
https://www.babeljs.cn/
https://babeljs.io/
pnpm add -D @rollup/plugin-babel
pnpm add -D @babel/core
pnpm add -D @babel/preset-env
新建babel.config.mjs
export default {presets: [['@babel/preset-env',{//是否忽略browserslistrc配置ignoreBrowserslistConfig: false,// 使用 "loose" 模式编译 ES2015+ 中的代码,允许生成与严格模式代码不完全相同的代码loose: true,//启用针对已知 Bug 的修复程序bugfixes: true,//禁止转换为其他类型的模块modules: false,//排除对typeof Symbol 表达式转换,因为目前的环境已经支持 Symbol 类型exclude: ['transform-typeof-symbol']}]]
}
修改rollup.config.mjs
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';export default {input: ['src/index.js'],output: [{file:"dist/bundle.js",format: 'umd',name: 'bundle',sourcemap: true,}],plugins: [nodeResolve(),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),]
};
修改index.js
const square = n => n * n;
console.log(square(10))
打包成功查看结果,可以看到将匿名函数改成function方式了
避免打包第三方库
如果你不想第三方库被打包进来,而可以在外面引入,配合使用的话,可以在rollup.config.js中配置external
修改index.js
import foo from './foo.js';
import $ from 'jquery';function testJquery(){$(function (){console.log('juqery加载完成')})
}
testJquery();
function aaa() {console.log(foo);
}
aaa();
const square = n => n * n;
console.log(square(10))
执行打包,可以看到把jQuery也打包进来了
修改rollup.config.mjs,主要增加external和output下的globals
import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';export default {input: ['src/index.js'],output: [{file:"dist/bundle.js",format: 'umd',name: 'bundle',sourcemap: true,globals: {jquery: '$'}}],plugins: [//terser(),nodeResolve(),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),],external:['jquery']
};
再次打包可以看到没有jQuery包的代码了
这样在使用的时候我们只需要在浏览器中自己引入jquery即可
配置css
安装postcss插件
pnpm add -D rollup-plugin-postcss
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'export default {input: ['src/index.js'],output: [{file:"dist/bundle.js",format: 'umd',name: 'bundle',sourcemap: true,globals: {jquery: '$'}}],plugins: [//terser(),nodeResolve(),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),postcss()],external:['jquery']
};
src下新建css文件夹,该文件夹下新建index.css
body{background: #ccc;
}
执行打包
css自动加浏览器前缀以及将css和js分开
pnpm add -D autoprefixer
修改index.css
@keyframes fadeIn {0% {opacity: 0;}100% {opacity: 1;}
}body {background: #ccc;animation-name: fadeIn;
}.autoplacement-example {display: grid;grid-template-columns: 1fr 1fr;grid-template-rows: auto auto;grid-gap: 20px;
}::placeholder {color: gray;
}
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'
import autoprefixer from "autoprefixer";export default {input: ['src/index.js'],output: [{file:"dist/bundle.js",format: 'umd',//assetFileNames: 'assets/[name]-[hash][extname]',name: 'bundle',sourcemap: true,globals: {jquery: '$'}}],plugins: [//terser(),nodeResolve(),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),postcss({extract: true, // 是否将CSS抽离成单独的文件sourceMap: true, // 是否生成 sourceMapplugins: [autoprefixer({// Autoprefixer 配置overrideBrowserslist: ["last 2 Chrome versions","> 1%","Firefox ESR","IE 9-11"],grid: true // 启用 CSS Grid 的自动前缀})],minimize: false, // 压缩 CSSextensions: ['.css'] // 处理的文件扩展名}),// css({// output: 'bundle.css'// })],external:['jquery']
};
打包
另外一种将css和js分开的方法
pnpm add -D rollup-plugin-css-only
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'export default {input: ['src/index.js'],output: [{file:"dist/bundle.js",format: 'umd',//assetFileNames: 'assets/[name]-[hash][extname]',name: 'bundle',sourcemap: true,globals: {jquery: '$'}}],plugins: [//terser(),nodeResolve(),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),//postcss(),css({output: 'bundle.css'})],external:['jquery']
};
打包之后js中就没有css文件了
配置scss
pnpm add -D rollup-plugin-sass
pnpm add -D postcss
https://www.npmjs.com/package/rollup-plugin-sass
src下新建scss文件夹,新建index.scss
$font-size: 14px;
$link-color:#ff0;::placeholder {color: gray;
}
.test{font-size: $font-size;a{color: $link-color;}
}
修改index.js
import foo from './foo.js';
import $ from 'jquery';
import "./css/index.css"
import './scss/index.scss'function testJquery(){$(function (){console.log('juqery加载完成')})
}
testJquery();
function aaa() {console.log(foo);
}
aaa();
const square = n => n * n;
console.log(square(10))
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'
import autoprefixer from "autoprefixer";
import sass from 'rollup-plugin-sass';
import postcss2 from 'postcss';export default {input: ['src/index.js'],output: [{file:"dist/bundle.js",format: 'umd',//assetFileNames: 'assets/[name]-[hash][extname]',name: 'bundle',sourcemap: true,globals: {jquery: '$'}}],plugins: [//terser(),nodeResolve(),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),postcss({extract: true, // 是否将CSS抽离成单独的文件sourceMap: true, // 是否生成 sourceMapplugins: [autoprefixer({// Autoprefixer 配置overrideBrowserslist: ["last 2 Chrome versions","> 1%","Firefox ESR","IE 9-11"],grid: false // 不启用 CSS Grid 的自动前缀})],minimize: false, // 压缩 CSSextensions: ['.css'], // 处理的文件扩展名inject: false, // 防止 Rollup 将 CSS 注入到 JavaScript 中}),sass({// sass 插件的配置output: 'dist/bundle2.css', // 输出 CSS 文件的路径processor:css => postcss2([autoprefixer({// Autoprefixer 配置overrideBrowserslist: ["last 2 Chrome versions","> 1%","Firefox ESR","IE 9-11"],grid: false // 不启用 CSS Grid 的自动前缀})]).process(css).then(result => result.css)}),// css({// output: 'bundle.css'// })],external:['jquery']
};
rollup-plugin-postcss
也可以处理scss
配置typescript
pnpm add -D @rollup/plugin-typescript --registry http://registry.npm.taobao.org
# pnpm add -D rollup-plugin-typescript2 --registry http://registry.npm.taobao.org
pnpm add -D tslib typescript --registry http://registry.npm.taobao.org
src下新建Greeter.ts
class Greeter {greeter: string;constructor(message: string) {this.greeter = message}greet() {return 'hello ts';}
}export default Greeter
src下新建hello.ts
import Greeter from "./Greeter";const a = new Greeter('ss');
a.greet();
修改index.js
import foo from './foo.js';
import $ from 'jquery';
import "./css/index.css"
import './scss/index.scss'
import './hello.js'function testJquery(){$(function (){console.log('juqery加载完成')})
}
testJquery();
function aaa() {console.log(foo);
}
aaa();
const square = n => n * n;
console.log(square(10));
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'
import autoprefixer from "autoprefixer";
import sass from 'rollup-plugin-sass';
import postcss2 from 'postcss';
import typescript from '@rollup/plugin-typescript';export default {input: ['src/index.js'],output: [{file: "dist/bundle.js",format: 'umd',//assetFileNames: 'assets/[name]-[hash][extname]',name: 'bundle',sourcemap: true,//dir: 'dist/bundle',globals: {jquery: '$'}}],plugins: [typescript({compilerOptions: {lib: ["es5", "es6", "dom"],target: "es5"},exclude: "node_modules/**",}),//terser(),nodeResolve(),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),postcss({extract: true, // 是否将CSS抽离成单独的文件sourceMap: true, // 是否生成 sourceMapplugins: [autoprefixer({// Autoprefixer 配置overrideBrowserslist: ["last 2 Chrome versions","> 1%","Firefox ESR","IE 9-11"],grid: false // 不启用 CSS Grid 的自动前缀})],minimize: false, // 压缩 CSSextensions: ['.css'], // 处理的文件扩展名inject: false, // 防止 Rollup 将 CSS 注入到 JavaScript 中}),// sass({// // sass 插件的配置// output: 'dist/bundle2.css', // 输出 CSS 文件的路径// processor:css => postcss2([autoprefixer({// // Autoprefixer 配置// overrideBrowserslist: [// "last 2 Chrome versions",// "> 1%",// "Firefox ESR",// "IE 9-11"// ],// grid: false // 不启用 CSS Grid 的自动前缀// })])// .process(css)// .then(result => result.css)// }),// css({// output: 'bundle.css'// })],external: ['jquery']
};
打包
去除头部
可用于在生成最终捆绑包之前从模块文件中删除横幅(例如许可证标头)。
pnpm add -D rollup-plugin-strip-banner --registry http://registry.npm.taobao.org
修改index.js
修改rollup.config.mjs
import terser from '@rollup/plugin-terser';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import {babel} from '@rollup/plugin-babel';
import postcss from 'rollup-plugin-postcss'
import css from 'rollup-plugin-css-only'
import autoprefixer from "autoprefixer";
import sass from 'rollup-plugin-sass';
import postcss2 from 'postcss';
import typescript from '@rollup/plugin-typescript';
import stripBanner from 'rollup-plugin-strip-banner';export default {input: ['src/index.js'],output: [{file: "dist/bundle.js",format: 'umd',//assetFileNames: 'assets/[name]-[hash][extname]',name: 'bundle',sourcemap: true,//dir: 'dist/bundle',globals: {jquery: '$'}}],plugins: [typescript({compilerOptions: {lib: ["es5", "es6", "dom"],target: "es5"},exclude: "node_modules/**",}),//terser(),nodeResolve(),stripBanner({include: '**/*.js',exclude: 'node_modules/**/*'}),commonjs(),babel({exclude: 'node_modules/**',babelHelpers: "bundled",}),postcss({extract: true, // 是否将CSS抽离成单独的文件sourceMap: true, // 是否生成 sourceMapplugins: [autoprefixer({// Autoprefixer 配置overrideBrowserslist: ["last 2 Chrome versions","> 1%","Firefox ESR","IE 9-11"],grid: false // 不启用 CSS Grid 的自动前缀})],minimize: false, // 压缩 CSSextensions: ['.css'], // 处理的文件扩展名inject: false, // 防止 Rollup 将 CSS 注入到 JavaScript 中}),// sass({// // sass 插件的配置// output: 'dist/bundle2.css', // 输出 CSS 文件的路径// processor:css => postcss2([autoprefixer({// // Autoprefixer 配置// overrideBrowserslist: [// "last 2 Chrome versions",// "> 1%",// "Firefox ESR",// "IE 9-11"// ],// grid: false // 不启用 CSS Grid 的自动前缀// })])// .process(css)// .then(result => result.css)// }),// css({// output: 'bundle.css'// })],external: ['jquery']
};
参考
https://blog.csdn.net/yutao618/article/details/116272769
https://blog.csdn.net/weixin_39216318/article/details/131431277
https://www.rollupjs.com/configuration-options/#external
https://github.com/rollup/plugins/tree/master