Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。
Rollup
使用ES6模块,而不是以前的特殊解决方案,如 CommonJS 和 AMD。
Rollup 更多是用于library打包
Webpack
具备强力的处理各类资源,构建 web应用
的能力,当然它也可以构建 library
;
Rollup
将自己定位于 “JavaScript 模块打包器,将小块代码编译成大块复杂的代码”,rollup.js更多是用于构建 library
;
rollup
更好的支持 Tree Shaking
,webpack
打包 es
模块尚属于试验阶段,打包的结果并不完美;rollup
相对学习成本更低;rollup
打包体积更小;// rollup.config.js
export default {
// 核心选项
input, // 必须
external,
plugins,
// 额外选项
onwarn,
// danger zone
acorn,
context,
moduleContext,
legacy
output: { // 必须 (如果要输出多个,可以是一个数组)
// 核心选项
file, // 必须
format, // 必须
name,
globals,
// 额外选项
paths,
banner,
footer,
intro,
outro,
sourcemap,
sourcemapFile,
interop,
// 高危选项
exports,
amd,
indent
strict
},
};
以下编译后的示例代码没有经过babel编译,下一节将讲述这部分
string
|string []
|{ [entryName: string]: string }
- 包的入口点 (例如:你的
main.js
或者app.js
或者index.js
)- 核心选项
如果你提供入口点数组或将名称映射到入口点的对象,它们将被捆绑到单独的输出块中。除非使用 output.file
选项,否则生成的块名称将跟随 output.entryFileNames
选项。当使用对象形式时,[name]
文件名的一部分将是对象属性的名称,而对于数组形式,它将是入口点的文件名。
单入口
// rollup.config.js
export default {
input: 'src/main.js',
};
多入口 —— 数组
export default {
input: [
'src/main.js',
'src/index.js'
],
output: {
dir: 'dist',
},
};
多入口 —— 对象
export default {
input: {
main1: 'src/main.js',
index1: 'src/index.js'
},
output: {
dir: 'dist',
entryFileNames: 'entry-[name].js'
},
};
Array
或者Object
定义包的输出
必须,核心选项
import pkg from './package.json'
// rollup.config.js
export default {
input: 'src/main.js',
output: {
file: pkg.main,
name: 'myMath',
format: 'umd'
},
};
// package.json
{
"main": "dist/index.js",
}
如果要输出多个,可以是一个数组
import pkg from './package.json'
// rollup.config.js
export default {
input: 'src/main.js',
output: [
{
file: pkg.browser,
name: 'myMath',
format: 'umd'
},
{
file: pkg.main,
format: 'cjs',
exports: 'auto'
},
{
file: pkg.module,
format: 'es'
}
],
};
// package.json
{
"main": "dist/cjs/index.js",
"module": "dist/es/index.js",
"browser": "dist/umd/index.js",
}
string
放置所有生成的chunks的目录。生成多个chunks的时候需要此选项。否则,可以改用file
选项。
String
- 输出的文件。也可用于生成 sourcemaps。只能在生成的块不超过一个时使用。
- 必须,核心选项
// rollup.config.js
export default {
input: 'src/main.js',
output: {
file: '"dist/index.js',
name: 'myMath',
format: 'umd'
},
};
String
,默认es
- 生成包的格式
- 核心选项
生成包的格式如下
amd
– 异步模块定义,用于像RequireJS这样的模块加载器;cjs
– CommonJS,适用于 Node 和 Browserify/Webpack(别名:commonjs
);es
– 将软件包保存为 ES 模块文件,在现代浏览器中可以通过
标签引入(别名:esm
, module
);iife
– 一个自动执行的功能,适合作为
标签。(如果要为应用程序创建一个捆绑包,您可能想要使用它,因为它会使文件大小变小。);umd
– 通用模块定义,以amd
,cjs
和 iife
为一体;system
- SystemJS 加载器格式 (别名:systemjs
);下面看一下常用的 cjs
、es
、umd
编译后的代码
export default (x, y) => {
return x + y
}
编译后
'use strict';
var main = (x, y) => {
return x + y
};
module.exports = main;
var main = (x, y) => {
return x + y
};
export { main as default };
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.myMath = factory());
})(this, (function () { 'use strict';
var main = (x, y) => {
return x + y
};
return main;
}));
String
- 变量名,当你的
format
为iife
/umd
时必须,同一页上的其他脚本可以访问这个变量。
// rollup.config.js
export default {
...,
output: {
file: 'bundle.js',
format: 'iife',
name: 'MyBundle'
}
};
// -> var MyBundle = (function () {...
{ [id: string]: string } | ((id: string) => string)
- 定义外部导入的全局模块,常配合 external 一起使用
- 用于
umd
/iife
包。
例如:在这样的情况下…
import $ from 'jquery';
我们想告诉 Rollup jquery
模块的id等同于 $
变量:
// rollup.config.js
export default {
...,
output: {
format: 'iife',
name: 'MyBundle',
globals: {
jquery: '$' // 此处 $ 是外部的引用,jquery是定义的内部模块
}
}
};
/*
var MyBundle = (function ($) {
// 代码到这里
}(window.jQuery));
*/.
string | ((assetInfo: AssetInfo) => string)
- 默认值:
"assets/[name]-[hash][extname]"
- 自定义生成资源的路径及命名
支持以下占位符:
[extname]
:资源的文件扩展名,包括前导点,例如.css
.[ext]
: 没有前导点的文件扩展名,例如css
.[hash]
:基于资源名称和内容的哈希。[name]
:资源的文件名,不包括任何扩展名。正斜杠/
可用于将文件放置在子目录中。使用函数时,assetInfo
是generateBundle
不带fileName
。 另请参阅 output.chunkFileNames,output.entryFileNames。
string | ((chunkInfo: ChunkInfo) => string)
- 默认值:
"[name]-[hash].js"
- 用于自定义代码拆分时创建的共享块的命名
模式支持以下占位符:
[format]
:在输出选项中定义的渲染格式,例如es
或cjs
。[hash]
:基于块内容及其所有依赖项内容的哈希。[name]
:块的名称。这可以通过output.manualChunks
选项显式设置,或者当块由插件创建时通过this.emitFile
. 否则,它将从块内容派生。正斜杠/
可用于将文件放置在子目录中。使用函数时,chunkInfo
它是generateBundle
不依赖文件名的属性的简化版本。另请参阅 output.assetFileNames,output.entryFileNames。
string | ((chunkInfo: ChunkInfo) => string)
- 默认值:
"[name].js"
- 用于从入口点创建的块
模式支持以下占位符:
[format]
:在输出选项中定义的渲染格式,例如es
或cjs
。[hash]
:基于入口点内容及其所有依赖项内容的哈希。[name]
:入口点的文件名(不带扩展名),除非输入的对象形式用于定义不同的名称。正斜杠/
可用于将文件放置在子目录中。使用函数时,chunkInfo
它是generateBundle
不依赖文件名的属性的简化版本。另请参阅 output.assetFileNames,output.chunkFileNames。
output.preserveModules设置选项时也将使用此模式。但是,这里有一组不同的占位符可用:
[format]
:输出选项中定义的渲染格式。[name]
:文件的文件名(不带扩展名)。[ext]
:文件的扩展名。[extname]
:文件的扩展名,如果它不为空,则为前缀。[assetExtname]
:文件的扩展名,如果它不为空且不是js
、jsx
、ts
或tsx
之一,则为前缀。
String
- 字符串以 前置/追加 到文件束(bundle)。(注意:“banner”和“footer”选项不会破坏sourcemaps)
// rollup.config.js
import pkg from './package.json';
export default {
...,
banner: `/* ${pkg.name} version ${pkg.version} */`,
footer: '/* follow me on CSDN @五虎战画戟 https://blog.csdn.net/qq_41887214 */'
};
String
- 类似于
banner
和footer
,将自定义的代码在放在生成的代码的内部
export default {
...,
intro: 'var ENVIRONMENT_INTRO = "production";',
outro: 'var ENVIRONMENT_OUTRO = "production";',
};
- Boolean,默认false
如果 true
,将创建一个单独的sourcemap文件。如果 inline
,sourcemap将作为数据URI附加到生成的output
文件中。
export default {
input: 'src/main.js',
output: {
file: 'dist/index.js',
sourcemap: true
},
};
String
使用什么导出模式。默认为auto
,它根据entry
模块导出的内容猜测你的意图:
default
– 如果你使用 export default ...
仅仅导出一个东西,那适合用这个named
– 如果你导出多个东西,适合用这个none
– 如果你不导出任何内容 (例如,你正在构建应用程序,而不是库),则适合用这个default
和 named
之间的区别会影响其他人如何使用文件束(bundle)。如果您使用default
,则CommonJS用户可以执行此操作,例如
var yourLib = require( 'your-lib' );
使用 named
,用户可以这样做:
var yourMethod = require( 'your-lib' ).yourMethod;
有点波折就是如果你使用named
导出,但是同时也有一个default
导出,用户必须这样做才能使用默认的导出:
var yourMethod = require( 'your-lib' ).yourMethod;
var yourLib = require( 'your-lib' )['default'];
Type: boolean
,默认: false
CLI: --preserveModules
/--no-preserveModules
使用原始模块名(及结构)作为文件名为所有模块创建单独的块;Tree-shaking仍然会被应用;
另一方面,如果插件(如@rollup/plugin-commonjs
)发出额外的“虚拟”文件来实现某些结果,这些文件将使用模式_virtual/fileName.js
作为实际文件发出。
rollup.config.js
import pkg from './package.json'
import path from 'path'
export default {
input: './src/index.js',
output: [
{
dir: path.dirname(pkg.main),
format: 'cjs',
exports: 'named', // 指定导出模式(自动、默认、命名、无)
preserveModules: true, // 保留模块结构
preserveModulesRoot: 'src', // 将保留的模块放在根级别的此路径下
},
{
dir: path.dirname(pkg.module),
format: 'es',
exports: 'named', // 指定导出模式(自动、默认、命名、无)
preserveModules: true, // 保留模块结构
preserveModulesRoot: 'src', // 将保留的模块放在根级别的此路径下
}
],
}
index.js
export * from './components/ButtonGroup'
export * from './components/Button'
export * from './components/Header'
export * from './components/Page'
pcakage.json
{
...
"main": "dist/lib/index.js",
"module": "dist/es/index.js"
...
}
源码目录结构
打包产物目录结构
Type: string
当preserveModules为true时,应该从输出中剥离的输入模块的目录路径。
示例:
export default {
input: ['src/module.js', `src/another/module.js`],
output: [
{
format: 'es',
dir: 'dist',
preserveModules: true,
preserveModulesRoot: 'src'
}
]
};
- (string | RegExp)[] | RegExp | string | (id: string, parentId: string, isResolved: boolean) => boolean
- 声明外部依赖,常配合 output.globals 使用
export default {
input: './src/index.js',
output: {
file: './lib/index.js',
name: 'myMath',
format: 'umd',
globals: {
jquery: '$',
}
},
external: ['jquery'] // 将[模块]视为外部依赖项
}
- Plugin | (Plugin | void)[]
- 插件
注意:插件要调用,(即 commonjs()
, 而不是 commonjs
)
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
export default {
entry: 'main.js',
plugins: [
resolve(),
commonjs()
]
};
Function
- 将拦截警告信息。如果没有提供,警告将被复制并打印到控制台。
警告是至少有一个code
和 message
属性的对象,这意味着您可以控制如何处理不同类型的警告:
onwarn (warning) {
// 跳过某些警告
if (warning.code === 'UNUSED_EXTERNAL_IMPORT') return;
// 抛出异常
if (warning.code === 'NON_EXISTENT_EXPORT') throw new Error(warning.message);
// 控制台打印一切警告
console.warn(warning.message);
}
许多警告也有一个loc
属性和一个frame
,你可以定位到警告的来源:
onwarn ({ loc, frame, message }) {
// 打印位置(如果适用)
if (loc) {
console.warn(`${loc.file} (${loc.line}:${loc.column}) ${message}`);
if (frame) console.warn(frame);
} else {
console.warn(message);
}
}
如果对你有用,点个赞支持下吧!