配置选项
核心功 能
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和iifesystem– 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()]
}
]
};