配置选项
核心功 能
external
类型: | (string | RegExp)[] | RegExp | string | (id: string, parentId: string, isResolved: boolean) => boolean |
CLI: | -e /--external <external-id,another-external-id,...> |
该选项用于匹配需要排除在 bundle 外部的模块,它的值可以是一个接收模块 id
参数并返回 true
(表示外部依赖)或 false
(表示非外部依赖)的函数,也可以是一个模块 ID 数组或者正则表达式。除此之外,它还可以只是单个的模块 ID 或正则表达式。被匹配的模块 ID 应该满足以下条件之一:
- 外部依赖的名称,需要和引入语句中写法完全一致。例如,如果想标记
import "dependency.js"
为外部依赖,就需要使用"dependency.js"
作为模块 ID;而如果要标记import "dependency"
为外部依赖,则使用"dependency"
。 - 解析过的模块 ID(如文件的绝对路径)。
// rollup.config.js
import { fileURLToPath } from 'node:url';
// ---cut-start---
/** @type {import('rollup').RollupOptions} */
// ---cut-end---
export default {
//...,
external: [
'some-externally-required-library',
fileURLToPath(
new URL(
'src/some-local-file-that-should-not-be-bundled.js',
import.meta.url
)
),
/node_modules/
]
};
请注意,如果要通过 /node_modules/
正则表达式过滤掉包的引入,例如 import {rollup} from 'rollup'
,需要先使用类似 @rollup/plugin-node-resolve 的插件,来将引入依赖解析到 node_modules
。
当用作命令行参数时,该选项的值应该是一个以逗号分隔的模块 ID 列表:
rollup -i src/main.js ... -e foo,bar,baz
当该选项的值为函数时,它提供了三个参数 (id, parent, isResolved)
,可以为你提供更细粒度的控制:
id
为相关模块 idparent
为进行引入的模块 idisResolved
表示id
是否已被插件等解析
当创建 iife
或 umd
格式的 bundle 时,你需要通过 output.globals
选项提供全局变量名,以替换掉外部引入。
如果一个相对引入,即以 ./
或 ../
开头,被标记为 external
,rollup 将在内部将该模块 ID 解析为绝对路径,以便引入的不同外部模块可以合并。当写入生成的 bundle 后,这些引入模块将再次被转换为相对引入。例如:
// 输入
// src/main.js (入口文件)
import x from '../external.js';
import './nested/nested.js';
console.log(x);
// src/nested/nested.js
// 如果引入依赖已存在,它将指向同一个文件
import x from '../../external.js';
console.log(x);
// 输出
// 不同的依赖将会合并
import x from '../external.js';
console.log(x);
console.log(x);
如果存在多个入口,rollup 会转换回相对引入的方式,就像 output.file
或 output.dir
与入口文件或所有入口文件位于相同目录。
input
类型: | string | string [] | { [entryName: string]: string } |
CLI: | -i /--input <filename> |
该选项用于指定 bundle 的入口文件(例如,你的 main.js
,app.js
或 index.js
文件)。如果值为一个入口文件的数组或一个将名称映射到入口文件的对象,那么它们将被打包到单独的输出 chunks。除非使用 output.file
选项,否则生成的 chunk 名称将遵循 output.entryFileNames
选项设置。当该选项的值为对象形式时,对象的属性名将作为文件名中的 [name]
,而对于值为数组形式,数组的值将作为入口文件名。
请注意,当选项的值使用对象形式时,可以通过在名称中添加 /
来将入口文件放入不同的子文件夹。以下例子将根据 entry-a.js
和 entry-b/index.js
,产生至少两个入口 chunks,即 index.js
文件将输出在 entry-b
文件夹中:
// rollup.config.js
// ---cut-start---
/** @type {import('rollup').RollupOptions} */
// ---cut-end---
export default {
// ...
input: {
a: 'src/main-a.js',
'b/index': 'src/main-b.js'
},
output: {
// ...
entryFileNames: 'entry-[name].js'
}
};
如果你想将一组文件转换为另一种格式,并同时保持文件结构和导出签名,推荐的方法是将每个文件变成一个入口文件,而不是使用 output.preserveModules
,后者可能会导出被除屑优化,并产生由插件创建的虚拟文件。你可以动态地处理,例如通过 glob
包。
// @filename: glob.d.ts
declare module 'glob' {
export function globSync(pattern: string): string[];
}
// @filename: index.js
// ---cut---
import { globSync } from 'glob';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
export default {
input: Object.fromEntries(
globSync('src/**/*.js').map(file => [
// 这里将删除 `src/` 以及每个文件的扩展名。
// 因此,例如 src/nested/foo.js 会变成 nested/foo
path.relative(
'src',
file.slice(0, file.length - path.extname(file).length)
),
// 这里可以将相对路径扩展为绝对路径,例如
// src/nested/foo 会变成 /project/src/nested/foo.js
fileURLToPath(new URL(file, import.meta.url))
])
),
output: {
format: 'es',
dir: 'dist'
}
};
如果某些插件在 buildStart
钩子结束前至少生成了一个 chunk(使用 this.emitFile
),则该选项可以省略。
当使用命令行时,多个入口只需要多次使用该选项输入。当作为第一个选项提供时,相当于不以 --input
为前缀:
rollup --format es --input src/entry1.js --input src/entry2.js
# 等同于
rollup src/entry1.js src/entry2.js --format es
可以使用 =
赋值来命名 chunk:
rollup main=src/entry1.js other=src/entry2.js --format es
可以使用引号指定包含空格的文件名:
rollup "main entry"="src/entry 1.js" "src/other entry.js" --format es
jsx
类型: | false | JsxPreset | JsxOptions |
CLI: | --jsx <preset> /--no-jsx |
默认: | false |
type JsxPreset = 'react' | 'react-jsx' | 'preserve' | 'preserve-react';
type JsxOptions =
| {
mode: 'preserve';
factory: string | null;
fragment: string | null;
importSource: string | null;
preset: JsxPreset | null;
}
| {
mode: 'classic';
factory: string;
fragment: string;
importSource: string | null;
preset: JsxPreset | null;
}
| {
mode: 'automatic';
factory: string;
importSource: string;
jsxImportSource: string;
preset: JsxPreset | null;
};
允许 Rollup 处理 JSX 语法,可以根据 jsx.mode
保留或转换它。如果设置为 false
,遇到 JSX 语法时将抛出错误。你也可以选择一个预设,将所有选项一起设置:
"react"
:将 JSX 转译为React.createElement
调用,其中React
是从"react"
默认导入的。这与在 TypeScript 编译器选项中设置"jsx": "react"
类似。({
mode: 'classic',
factory: 'React.createElement',
fragment: 'React.Fragment',
importSource: 'react'
});"react-jsx"
:将使用 React 17 引入的新版优化后的 React 转换,类似于在 TypeScript 编译器选项中设置"jsx": "react-jsx"
。({
mode: 'automatic',
factory: 'React.createElement',
importSource: 'react',
jsxImportSource: 'react/jsx-runtime'
});"preserve"
:将在输出中保留 JSX。这仍然会去屑优化掉未使用的 JSX 代码,并且如果在输出中存在冲突,可能会重命名 JSX 标识符。({
mode: 'preserve',
factory: null,
fragment: null,
importSource: null
});"preserve-react"
:将在输出中保留 JSX,但确保"react"
的默认导出作为名为React
的变量在作用域中。({
mode: 'preserve',
factory: 'React.createElement',
fragment: 'React.Fragment',
importSource: 'react'
});
jsx.mode
类型: | "preserve" | "classic" | "automatic" |
CLI: | --jsx.mode <mode> |
默认: | "classic" |
该选项将决定如何处理 JSX:
-
"preserve"
:将在输出中保持 JSX 语法。 -
"classic"
:将执行 JSX 转换,因为旧版本的 React 或其他框架(例如 Preact)需要它。例如,以下是你如何为 Preact 配置 jsx 的方法:({
mode: 'classic',
factory: 'h',
fragment: 'Fragment',
importSource: 'preact'
});将执行以下转换:
// 输入
console.log(<div>hello</div>);
// 输出
import { h } from 'preact';
console.log(/*#__PURE__*/ h('div', null, 'hello')); -
"automatic"
:将使用 React 17 引入的 新版 JSX 转换 执行 JSX 转换。在此模式下,Rollup 将尝试从jsx.jsxImportSource
导入工具函数来转换 JSX。由于存在某些边界情况,当 使用key
属性和扩展属性 时,此模式可能仍会回退到使用"classic"
转换形式。为此,你仍然可以指定jsx.importSource
,jsx.factory
和jsx.fragment
来配置"classic"
模式。
jsx.factory
类型: | string | null |
CLI: | --jsx.factory <factory> |
默认: | "React.createElement" or null |
该选项为 Rollup 在 "classic"
模式或 "automatic"
模式的回退中用来创建 JSX 元素的函数。对于 React,这通常是 React.createElement
,对于其他框架,则可能为 h
。在 "preserve"
模式下,如果指定了 jsx.importSource
,则将确保工厂函数在作用域中,否则同名的全局变量不会被局部变量覆盖。只有在 "preserve"
模式下,才可以将此值设置为 null
,在这种情况下,Rollup 不会注意保持任何特定的工厂函数在作用域中。
如果值包含 "."
,例如 React.createElement
,并且指定了 jsx.importSource
,Rollup 将假定左侧部分(例如 React
)指的是 jsx.importSource
的默认导出。否则,Rollup 将假定它是一个命名导出。
jsx.fragment
类型: | string | null |
CLI: | --jsx.fragment <fragment> |
默认: | "React.Fragment" or null |
Rollup 用来创建 JSX 片段的元素函数。对于 React,这通常是 React.Fragment
,对于其他框架,则是 Fragment
。在 "preserve"
模式下,如果指定了 jsx.importSource
,则将确保片段在作用域中,否则同名的全局变量不会被局部变量覆盖。只有在 "preserve"
模式下,才可以将此值设置为 null
,在这种情况下,Rollup 不会注意保持任何特定的片段函数在作用域中。
如果值包含 "."
,例如 React.Fragment
,并且指定了 jsx.importSource
,Rollup 将假定左边的部分(例如 React
)指的是 jsx.importSource
的默认导出。否则,Rollup 将假定它是一个命名导出。
jsx.importSource
类型: | string | null |
CLI: | --jsx.importSource <library> |
默认: | null |
从哪里导入 元素工厂函数及片段元素。如果设为 null
,Rollup 将假定 jsx.factory
和 jsx.fragment
指的是全局变量,并确保它们不会被同名的本地变量覆盖。
jsx.jsxImportSource
类型: | string |
CLI: | --jsx.jsxImportSource <library> |
默认: | "react/jsx-runtime" |
当使用 "automatic"
模式时,将指定从哪里导入进行该转换所需的 jsx
、jsxs
和 Fragment
辅助函数。这些是无法从全局变量获取的。
jsx.preset
类型: | JsxPreset |
CLI: | --jsx.preset <value> |
允许选择上述预设中的一个,同时覆盖一些选项。
// ---cut-start---
/** @type {import('rollup').RollupOptions} */
// ---cut-end---
export default {
jsx: {
preset: 'react',
importSource: 'preact',
factory: 'h'
}
// ...
};
output.dir
类型: | string |
CLI: | -d /--dir <dirname> |
该选项用于指定所有生成的 chunk 被放置在哪个目录中。如果生成一个以上的 chunk,那么这个选项是必需的。否则,可以使用 file
选项来代替。
output.file
类型: | string |
CLI: | -o /--file <filename> |
该选项用于指定要写入的文件。如果适用的话,也可以用于生成 sourcemap。只有在生成的 chunk 不超过一个的情况下才可以使用。
output.format
类型: | string |
CLI: | -f /--format <formatspecifier> |
默认: | "es" |
该选项用于指定生成的 bundle 的格式。满足以下其中之一:
amd
– 异步模块加载,适用于 RequireJS 等模块加载器cjs
– CommonJS,适用于 Node 环境和其他打包工具(别名:commonjs
)es
– 将 bundle 保留为 ES 模块文件,适用于其他打包工具,以及支持<script type=module>
标签的浏览器。(别名:esm
,module
)iife
– 自执行函数,适用于<script>
标签(如果你想为你的应用程序创建 bundle,那么你可能会使用它)。iife
表示“自执行 函数表达式”umd
– 通用模块定义规范,同时支持amd
,cjs
和iife
system
– SystemJS 模块加载器的原生格式(别名:systemjs
)
output.globals
类型: | { [id: string]: string } | ((id: string) => string) |
CLI: | -g /--globals <external-id:variableName,another-external-id:anotherVariableName,...> |
该选项用于在 umd
/ iife
bundle 中,使用 id: variableName
键值对指定外部依赖。例如,在这样的情况下:
import $ from 'jquery';
我们需要告诉 Rollup jquery
是外部依赖,jquery
模块的 ID 为全局变量 $
:
// rollup.config.js
// ---cut-start---
/** @type {import('rollup').RollupOptions} */
// ---cut-end---
export default {
// ...
external: ['jquery'],
output: {
format: 'iife',
name: 'MyBundle',
globals: {
jquery: '$'
}
}
};
/*
var MyBundle = (function ($) {
// 这里编辑代码
}($));
*/
或者,可以提供一个函数,将外部模块的 ID 变成一个全局变量名。
当作为命令行参数时,该选项的值应该是以逗号分隔的 id:variableName
键值对列表:
rollup -i src/main.js ... -g jquery:$,underscore:_
要告诉 Rollup 用全局变量替换本地文件时,请使用一个绝对路径的 ID。
// rollup.config.js
import { fileURLToPath } from 'node:url';
const externalId = fileURLToPath(
new URL(
'src/some-local-file-that-should-not-be-bundled.js',
import.meta.url
)
);
// ---cut-start---
/** @type {import('rollup').RollupOptions} */
// ---cut-end---
export default {
//...,
external: [externalId],
output: {
format: 'iife',
name: 'MyBundle',
globals: {
[externalId]: 'globalVariable'
}
}
};
output.name
类型: | string |
CLI: | -n /--name <variableName> |
对于输出格式为 iife
/ umd
的 bundle 来说,若想要使用全局变量名来表示你的 bundle 时,该选项是必要的。同一页面上的其他脚本可以使用这个变量名来访问你的 bundle 输出。
// rollup.config.js
// ---cut-start---
/** @type {import('rollup').RollupOptions} */
// ---cut-end---
export default {
// ...
output: {
file: 'bundle.js',
format: 'iife',
name: 'MyBundle'
}
};
// var MyBundle = (function () {...
该选项也支持命名空间,即可以包含点 .
的名字。最终生成的 bundle 将包含命名空间所需要的设置。
rollup -n "a.b.c"
/* ->
this.a = this.a || {};
this.a.b = this.a.b || {};
this.a.b.c = ...
*/
output.plugins
类型: | MaybeArray<MaybePromise<OutputPlugin | void>> |
该选项用于指定输出插件。关于如何使用特定输出的插件,请查看 使用输出插件,关于如何编写自己的插件,请查看 插件。对于从包中引入的插件,记得要调用引入的插件函数(即调用 commonjs()
,而不仅仅是 commonjs
)。返回值为假的插件将被忽略,这样可以用来灵活启用或禁用插件。嵌套的插件将扁平化。异步插件将等待和被解决。
并非所有的插件都可以通过该选项使用。output.plugins
仅限于在 bundle.generate()
或 bundle.write()
阶段,即在 Rollup 的主要分析完成后运行钩子的插件才可使用。如果你是一个插件作者,请查看 输出生成钩子 章节以了解哪些钩子可以使用。
以下是一个使用压缩插件作用于其中一个输出的例子:
// rollup.config.js
import terser from '@rollup/plugin-terser';
// ---cut-start---
/** @type {import('rollup').RollupOptions} */
// ---cut-end---
export default {
input: 'main.js',
output: [
{
file: 'bundle.js',
format: 'es'
},
{
file: 'bundle.min.js',
format: 'es',
plugins: [terser()]
}
]
};