Rollup 配置 #
配置文件结构 #
基本结构 #
javascript
// rollup.config.js
export default {
// 核心配置
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
// 插件配置
plugins: [],
// 高级配置
external: [],
onwarn: (warning) => {},
cache: true,
// 监听配置
watch: {}
};
配置类型定义 #
typescript
interface RollupOptions {
input: InputOption;
output: OutputOptions | OutputOptions[];
plugins?: Plugin[];
external?: ExternalOption;
onwarn?: WarningHandler;
cache?: boolean | RollupCache;
watch?: WatcherOptions;
maxParallelFileOps?: number;
preserveEntrySignatures?: PreserveEntrySignaturesOption;
shimMissingExports?: boolean;
treeshake?: TreeshakeOptions | boolean;
context?: string;
moduleContext?: ((id: string) => string) | { [id: string]: string };
}
输入配置(input) #
字符串形式 #
javascript
export default {
input: 'src/main.js'
};
数组形式 #
javascript
export default {
input: ['src/main.js', 'src/admin.js']
};
对象形式 #
javascript
export default {
input: {
main: 'src/main.js',
admin: 'src/admin.js',
vendor: 'src/vendor.js'
}
};
带选项的输入 #
javascript
export default {
input: {
main: {
import: 'src/main.js',
preserveSignature: 'strict'
}
}
};
输出配置(output) #
完整输出选项 #
javascript
export default {
output: {
// 基础选项
file: 'dist/bundle.js',
format: 'es',
name: 'MyLibrary',
// 文件命名
assetFileNames: 'assets/[name]-[hash][extname]',
chunkFileNames: 'chunks/[name]-[hash].js',
entryFileNames: '[name].js',
// Source Map
sourcemap: true,
sourcemapBaseUrl: 'https://example.com/maps/',
sourcemapExcludeSources: false,
sourcemapFile: 'dist/bundle.js.map',
sourcemapPathTransform: (relativePath) => `src/${relativePath}`,
// 代码注入
banner: '/* My Library v1.0.0 */',
footer: '/* End of library */',
intro: 'var ENV = "production";',
outro: 'console.log("Library loaded");',
// 格式化
compact: false,
extend: false,
exports: 'auto',
interop: 'auto',
// 依赖
globals: { lodash: '_' },
// 模块保留
preserveModules: false,
preserveModulesRoot: 'src',
// 其他
hoistTransitiveImports: true,
minifyInternalExports: false,
preferConst: false,
generatedCode: { constBindings: false }
}
};
输出格式详解 #
ES Module(es) #
javascript
output: {
format: 'es',
// 输出示例:
// import { foo } from './foo.js';
// export default function() { ... }
}
特点:
- 现代 JavaScript 模块格式
- 支持 Tree-shaking
- 浏览器和 Node.js 原生支持
CommonJS(cjs) #
javascript
output: {
format: 'cjs',
exports: 'auto', // 'auto' | 'named' | 'default'
// 输出示例:
// 'use strict';
// var foo = require('./foo.js');
// module.exports = function() { ... }
}
特点:
- Node.js 模块格式
- 兼容性好
- 不支持 Tree-shaking
UMD(umd) #
javascript
output: {
format: 'umd',
name: 'MyLibrary',
exports: 'auto',
extend: false, // 是否扩展全局变量
amd: {
id: 'my-library' // AMD 模块 ID
},
// 输出示例:
// (function (global, factory) {
// typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
// typeof define === 'function' && define.amd ? define(factory) :
// (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MyLibrary = factory());
// })(this, (function () { ... }));
}
特点:
- 通用模块定义
- 支持 AMD、CommonJS、全局变量
- 适用于库发布
IIFE(iife) #
javascript
output: {
format: 'iife',
name: 'MyApp',
extend: false,
// 输出示例:
// var MyApp = (function () {
// 'use strict';
// // ...代码
// })();
}
特点:
- 立即执行函数
- 适合浏览器直接使用
- 不需要模块系统
System(system) #
javascript
output: {
format: 'system',
// 输出示例:
// System.register('my-lib', [], function (exports) {
// 'use strict';
// return { execute: function () { ... } };
// });
}
特点:
- SystemJS 模块格式
- 支持动态加载
文件命名模板 #
javascript
output: {
// 入口文件命名
entryFileNames: '[name].js',
// 可用占位符:
// [name] - 入口名称
// [hash] - 内容哈希
// [format] - 输出格式
// 代码块命名
chunkFileNames: 'chunks/[name]-[hash].js',
// 静态资源命名
assetFileNames: 'assets/[name]-[hash][extname]'
}
多输出配置 #
javascript
export default {
input: 'src/index.js',
output: [
{
file: 'dist/my-lib.cjs.js',
format: 'cjs',
sourcemap: true
},
{
file: 'dist/my-lib.esm.js',
format: 'es',
sourcemap: true
},
{
file: 'dist/my-lib.umd.js',
format: 'umd',
name: 'MyLib',
sourcemap: true,
globals: { lodash: '_' }
}
]
};
外部依赖配置(external) #
数组形式 #
javascript
export default {
external: [
'lodash',
'axios',
'vue',
'vue-router'
]
};
正则表达式 #
javascript
export default {
external: [
/^lodash/,
/^@vue/,
/^@my-org\//
]
};
函数形式 #
javascript
export default {
external: (id, parentId, isResolved) => {
// id: 模块 ID
// parentId: 父模块 ID
// isResolved: 是否已解析
// 排除所有 node_modules
if (id.includes('node_modules')) {
return true;
}
// 排除特定模块
if (id === 'lodash' || id.startsWith('lodash/')) {
return true;
}
return false;
}
};
对象形式 #
javascript
export default {
external: {
lodash: '_',
jquery: '$',
axios: 'axios'
}
};
排除 Node.js 内置模块 #
javascript
import { builtinModules } from 'module';
export default {
external: [
...builtinModules,
...builtinModules.map(m => `node:${m}`)
]
};
插件配置(plugins) #
基本用法 #
javascript
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
export default {
plugins: [
resolve(),
commonjs(),
terser()
]
};
插件顺序 #
插件执行顺序很重要:
javascript
export default {
plugins: [
// 1. 解析模块
resolve(),
// 2. 转换 CommonJS
commonjs(),
// 3. 转换 TypeScript
typescript(),
// 4. 处理 JSON
json(),
// 5. 其他转换
babel({ babelHelpers: 'bundled' }),
// 6. 压缩(最后执行)
terser()
]
};
条件插件 #
javascript
const isProduction = process.env.NODE_ENV === 'production';
export default {
plugins: [
resolve(),
commonjs(),
isProduction && terser()
].filter(Boolean)
};
插件配置选项 #
javascript
import resolve from '@rollup/plugin-node-resolve';
export default {
plugins: [
resolve({
browser: true,
dedupe: ['vue'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
mainFields: ['browser', 'module', 'main'],
preferBuiltins: false
})
]
};
高级配置选项 #
preserveEntrySignatures #
控制入口导出的保留方式:
javascript
export default {
input: 'src/main.js',
preserveEntrySignatures: 'strict', // 'strict' | 'allow-extension' | false
output: {
format: 'es'
}
};
| 值 | 描述 |
|---|---|
'strict' |
保留所有入口导出(默认) |
'allow-extension' |
允许移除未使用的导出 |
false |
不保留入口导出 |
shimMissingExports #
为缺失的导出创建 shim:
javascript
export default {
input: 'src/main.js',
shimMissingExports: true
};
// 缺失的导出会被替换为 undefined
treeshake #
Tree-shaking 配置:
javascript
export default {
treeshake: {
annotations: true, // 使用注释标记
moduleSideEffects: true, // 模块副作用
propertyReadSideEffects: true,
tryCatchDeoptimization: true,
unknownGlobalSideEffects: true
}
};
context #
设置 this 的值:
javascript
export default {
context: 'window'
};
moduleContext #
为特定模块设置 this:
javascript
export default {
moduleContext: {
'src/legacy.js': 'window',
'src/node-script.js': 'global'
}
};
onwarn #
自定义警告处理:
javascript
export default {
onwarn: (warning, warn) => {
// 忽略特定警告
if (warning.code === 'THIS_IS_UNDEFINED') {
return;
}
// 自定义处理
if (warning.code === 'CIRCULAR_DEPENDENCY') {
console.log('Circular dependency detected:', warning.message);
return;
}
// 使用默认处理
warn(warning);
}
};
cache #
启用/禁用缓存:
javascript
export default {
cache: true // 默认 true
};
maxParallelFileOps #
最大并行文件操作数:
javascript
export default {
maxParallelFileOps: 20 // 默认 20
};
监听配置(watch) #
基本配置 #
javascript
export default {
watch: {
buildDelay: 300,
clearScreen: true,
skipWrite: false,
chokidar: {
usePolling: true
}
}
};
监听选项详解 #
javascript
export default {
watch: {
// 构建延迟(毫秒)
buildDelay: 300,
// 是否清屏
clearScreen: true,
// 是否跳过写入文件
skipWrite: false,
// 包含的文件
include: ['src/**'],
// 排除的文件
exclude: ['node_modules/**', 'dist/**'],
// chokidar 选项
chokidar: {
usePolling: true,
interval: 100,
binaryInterval: 300,
alwaysStat: false,
ignoreInitial: true,
awaitWriteFinish: {
stabilityThreshold: 2000,
pollInterval: 100
}
}
}
};
完整配置示例 #
库开发配置 #
javascript
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import terser from '@rollup/plugin-terser';
import dts from 'rollup-plugin-dts';
const isProduction = process.env.NODE_ENV === 'production';
export default [
// JavaScript 打包
{
input: 'src/index.ts',
output: [
{
file: 'dist/my-lib.cjs.js',
format: 'cjs',
sourcemap: true,
exports: 'named'
},
{
file: 'dist/my-lib.esm.js',
format: 'es',
sourcemap: true
},
{
file: 'dist/my-lib.umd.js',
format: 'umd',
name: 'MyLib',
sourcemap: true,
globals: {
lodash: '_'
}
}
],
external: ['lodash', 'axios'],
plugins: [
resolve({
extensions: ['.ts', '.js']
}),
commonjs(),
typescript({
tsconfig: './tsconfig.json'
}),
isProduction && terser()
].filter(Boolean)
},
// 类型声明文件
{
input: 'dist/types/index.d.ts',
output: {
file: 'dist/my-lib.d.ts',
format: 'es'
},
plugins: [dts()]
}
];
应用开发配置 #
javascript
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import terser from '@rollup/plugin-terser';
import livereload from 'rollup-plugin-livereload';
import serve from 'rollup-plugin-serve';
const isProduction = process.env.NODE_ENV === 'production';
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
name: 'App',
sourcemap: !isProduction,
banner: '// My App v1.0.0'
},
plugins: [
resolve({
browser: true
}),
commonjs(),
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**'
}),
!isProduction && serve({
contentBase: 'dist',
port: 3000
}),
!isProduction && livereload({
watch: 'dist'
}),
isProduction && terser()
].filter(Boolean),
watch: {
clearScreen: false
}
};
组件库配置 #
javascript
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import postcss from 'rollup-plugin-postcss';
import vue from 'rollup-plugin-vue';
export default {
input: 'src/components/index.ts',
output: {
dir: 'dist',
format: 'es',
preserveModules: true,
preserveModulesRoot: 'src',
sourcemap: true
},
external: ['vue', 'vue-router'],
plugins: [
resolve({
extensions: ['.ts', '.js', '.vue']
}),
commonjs(),
vue(),
typescript(),
postcss({
extract: true,
minimize: true
})
]
};
配置文件高级用法 #
动态配置 #
javascript
export default async () => {
const pkg = await import('./package.json', { assert: { type: 'json' } });
return {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es',
banner: `// ${pkg.name} v${pkg.version}`
}
};
};
环境变量配置 #
javascript
const env = process.env.NODE_ENV || 'development';
const config = require(`./config/${env}.json`);
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
intro: `var CONFIG = ${JSON.stringify(config)};`
}
};
多环境配置 #
javascript
// rollup.config.js
const configs = {
development: {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
sourcemap: true
}
},
production: {
input: 'src/main.js',
output: {
file: 'dist/bundle.min.js',
format: 'iife',
sourcemap: false
},
plugins: [terser()]
}
};
export default configs[process.env.NODE_ENV || 'development'];
配置验证 #
类型检查 #
typescript
import type { RollupOptions } from 'rollup';
const config: RollupOptions = {
input: 'src/main.ts',
output: {
file: 'dist/bundle.js',
format: 'es'
}
};
export default config;
配置验证函数 #
javascript
function validateConfig(config) {
if (!config.input) {
throw new Error('Missing input configuration');
}
if (!config.output) {
throw new Error('Missing output configuration');
}
if (config.output.format && !['es', 'cjs', 'umd', 'iife', 'system'].includes(config.output.format)) {
throw new Error(`Invalid format: ${config.output.format}`);
}
return config;
}
export default validateConfig({
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'es'
}
});
下一步 #
现在你已经深入了解了 Rollup 的配置选项,接下来学习 插件系统 掌握如何扩展 Rollup 的功能!
最后更新:2026-03-28