官网
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下需要指定name
name: '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 / system
name:'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, // 是否生成 sourceMap
plugins: [
autoprefixer({
// Autoprefixer 配置
overrideBrowserslist: [
"last 2 Chrome versions",
"> 1%",
"Firefox ESR",
"IE 9-11"
],
grid: true // 启用 CSS Grid 的自动前缀
})
],
minimize: false, // 压缩 CSS
extensions: ['.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, // 是否生成 sourceMap
plugins: [
autoprefixer({
// Autoprefixer 配置
overrideBrowserslist: [
"last 2 Chrome versions",
"> 1%",
"Firefox ESR",
"IE 9-11"
],
grid: false // 不启用 CSS Grid 的自动前缀
})
],
minimize: false, // 压缩 CSS
extensions: ['.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, // 是否生成 sourceMap
plugins: [
autoprefixer({
// Autoprefixer 配置
overrideBrowserslist: [
"last 2 Chrome versions",
"> 1%",
"Firefox ESR",
"IE 9-11"
],
grid: false // 不启用 CSS Grid 的自动前缀
})
],
minimize: false, // 压缩 CSS
extensions: ['.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