Rollup 是一个模块打包工具,主要用于将 ES6 模块转换为其他格式,以便在各种环境中使用。它支持多种输出格式,包括 ES5、AMD、CommonJS 和 UMD,并通过插件机制提供多种扩展功能,如代码压缩和环境变量注入。这些特性使得 Rollup 成为处理现代前端模块化开发的一种非常有效的工具。
Rollup是什么 Rollup的基本概念Rollup 是一个模块打包工具,主要用于将 ES6 模块(ESM)转换为其他格式(如 ES5、AMD、UMD 等),以便在各种环境中使用。它支持各种前端模块格式,包括 CommonJS(CJS) 和 AMD,可以将多个小模块打包成一个或多个较大的模块或文件,从而使前端应用更易于管理和维护。Rollup 的设计目标是提供一种高效的模块打包方式,以提高代码的可读性和运行时性能。
Rollup在前端开发中的作用在前端开发过程中,使用模块化编程可以使得代码更加清晰、易于维护。然而,不同的环境对模块的支持不同,例如,浏览器通常不直接支持 ES6 模块。此外,开发者可能需要将多个小模块打包成一个文件,以减少 HTTP 请求。
Rollup 提供了将 ES6 模块转换为其他格式的功能,使得代码可以在不同环境中运行。它支持多种输出格式,适用于不同的场景:
- ES5: 可以在不支持 ES6 模块的旧浏览器中运行。
- AMD: 可以在使用 RequireJS 或其他 AMD 兼容库的环境中运行。
- CommonJS: 可以在 Node.js 环境中运行。
- UMD: 可以在浏览器和 Node.js 环境中通用。
此外,Rollup 通过引入插件机制,可以实现代码压缩、源码映射、环境变量注入等多种功能,以满足前端开发中的各种需求。这些特性使得 Rollup 成为处理现代前端模块化开发的一种非常有效的工具。
Rollup的安装与配置 使用npm或yarn安装RollupRollup 可以通过 npm 或 yarn 安装。以下是使用 npm 和 yarn 的安装命令:
npm install --save-dev rollup
yarn add rollup --dev
这两个命令会将 Rollup 安装为开发依赖项。
简单的配置文件介绍Rollup 使用配置文件来定义打包的规则和参数。配置文件通常保存为 rollup.config.js
,你可以根据自己的需要自定义配置。
基本配置文件示例
// rollup.config.js
import { rollup } from 'rollup';
export default {
input: 'src/index.js', // 入口文件
output: {
file: 'dist/bundle.js', // 输出文件
format: 'es' // 输出格式(es、iife、cjs、amd、umd)
},
plugins: [] // 插件列表
};
配置项说明
input
: 指定输入文件的路径。output
: 定义输出文件的路径和格式。file
: 输出文件的路径。format
: 输出文件的格式,支持多种格式:es
,iife
,cjs
,amd
,umd
。
plugins
: 插件列表,用于扩展 Rollup 的功能。
使用配置文件打包
在命令行中执行以下命令来运行 Rollup 并使用配置文件:
npx rollup -c
这将使用 rollup.config.js
文件中的设置进行打包。
首先,创建一个 rollup.config.js
文件,定义基本的打包配置。
// rollup.config.js
import { rollup } from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true // 优先使用内置模块
})
]
};
输入与输出配置
input
: 指定要打包的源文件路径。output
: 定义打包后的输出路径和格式。file
: 输出文件的路径。format
: 输出文件的格式,如es
、iife
、cjs
、amd
、umd
。
插件配置
- 插件列表:这里使用了
@rollup/plugin-node-resolve
插件来解析和打包模块依赖。
Rollup 的强大之处在于可以使用各种插件来扩展其功能,例如代码压缩、环境变量注入等。
代码压缩插件
使用 @rollup/plugin-terser
插件来压缩代码。
import { rollup } from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
import { terser } from '@rollup/plugin-terser';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true
}),
terser({
compress: true // 是否压缩代码
})
]
};
环境变量注入插件
使用 @rollup/plugin-env
插件来注入环境变量。
```js.
import { rollup } from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
import env from '@rollup/plugin-env';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true
}),
env()
]
};
这些插件允许你在不同的开发环境中注入不同的变量,例如在生产环境中注入 `process.env.NODE_ENV` 为 `'production'`。
### 使用内建插件
Rollup 还提供了许多内建插件,例如 `@rollup/plugin-commonjs` 用于将 CommonJS 模块转换为 ES 模块。
```js
import { rollup } from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true
}),
commonjs({
include: /node_modules\/(.*)/, // 包含的模块
exclude: /node_modules\/(@babel\/runtime)/ // 排除的模块
})
]
};
这些配置和插件的组合允许你根据项目需求自定义打包过程。
Rollup的常用插件 插件的基本介绍Rollup 的插件机制允许扩展其功能和行为。下面介绍几个常用的插件及其功能。
@rollup/plugin-node-resolve
@rollup/plugin-node-resolve
插件用于解析模块依赖,使得 Rollup 可以正确处理外部模块的引入。
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true // 优先使用内置模块
})
]
};
@rollup/plugin-terser
@rollup/plugin-terser
插件用于压缩代码,减少文件大小,提高加载速度。
import { terser } from '@rollup/plugin-terser';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
terser({
compress: true // 是否压缩代码
})
]
};
@rollup/plugin-env
@rollup/plugin-env
插件用于注入环境变量,使代码在不同环境下运行时更具灵活性。
import env from '@rollup/plugin-env';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
env()
]
};
@rollup/plugin-commonjs
@rollup/plugin-commonjs
插件用于将 CommonJS 模块转换为 ES 模块。
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
commonjs({
include: /node_modules\/(.*)/, // 包含的模块
exclude: /node_modules\/(@babel\/runtime)/ // 排除的模块
})
]
};
这些插件可以单独使用,也可以组合使用,以满足复杂的打包需求。
常用插件的实际应用示例1:使用 @rollup/plugin-node-resolve 和 @rollup/plugin-terser
假设你有一个简单的项目,包含以下文件结构:
src/
|- index.js
|- utils.js
其中 index.js
引用了 utils.js
。
// src/index.js
import utils from './utils';
utils.greet();
// src/utils.js
export function greet() {
console.log('Hello, World!');
}
在 rollup.config.js
中配置 Rollup 使用 @rollup/plugin-node-resolve
和 @rollup/plugin-terser
插件:
import resolve from '@rollup/plugin-node-resolve';
import terser from '@rollup/plugin-terser';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true
}),
terser({
compress: true
})
]
};
运行打包命令:
npx rollup -c
打包后,dist/bundle.js
文件将会被压缩并包含 utils
模块。
示例2:使用 @rollup/plugin-env
继续上面的例子,假设你希望在不同的环境中注入不同的变量。可以在 rollup.config.js
中配置 @rollup/plugin-env
插件:
import env from '@rollup/plugin-env';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
env()
]
};
在 index.js
中使用环境变量:
// src/index.js
console.log(process.env.NODE_ENV); // 'development' 或 'production'
在命令行中设置环境变量:
export NODE_ENV=development
npx rollup -c
这样,process.env.NODE_ENV
将会根据设置的环境变量自动注入到打包后的代码中。
示例3:使用 @rollup/plugin-commonjs
假设你使用了一些 CommonJS 模块,需要将其转换为 ES 模块。例如,你使用了 lodash
库:
// src/index.js
import _ from 'lodash';
console.log(_.map([1, 2, 3], n => n * 2));
在 rollup.config.js
中配置 @rollup/plugin-commonjs
插件:
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
commonjs({
include: /node_modules\/(.*)/, // 包含的模块
exclude: /node_modules\/(@babel\/runtime)/ // 排除的模块
})
]
};
运行打包命令:
npx rollup -c
这样,lodash
库将被正确解析并包含在打包后的文件中。
Rollup 的打包过程可以分为以下几个主要步骤:
- 解析模块:Rollup 会解析所有的入口文件及其依赖,找到需要打包的所有模块。
- 转换模块:将模块转换为 ES6 模块格式,方便后续的打包处理。
- 生成模块图:构建模块之间的依赖关系图,确定模块的引用顺序。
- 打包输出:将转换后的模块按指定的输出格式输出,生成最终的打包文件。
解析模块
Rollup 会读取配置文件中的入口文件,并递归解析该文件及其所有依赖模块。解析过程中,Rollup 会使用 @rollup/plugin-node-resolve
插件来查找和解析依赖模块。
转换模块
在转换模块阶段,Rollup 会将解析到的模块转换为 ES6 模块格式,这样可以统一处理不同类型的模块。例如,如果输入文件是 CommonJS 模块,则会使用 @rollup/plugin-commonjs
插件将其转换为 ES6 模块。
生成模块图
Rollup 会生成一个模块依赖树,确定模块之间的引用顺序。这个依赖树用于后续打包输出时决定模块的输出顺序。
打包输出
在打包输出阶段,Rollup 会根据配置文件中的输出选项,将转换后的模块输出为指定格式的文件。输出格式包括 ES5、IIFE(立即执行函数)、CommonJS、AMD、UMD 等。
打包流程的详细说明- 配置文件读取:Rollup 首先读取配置文件
rollup.config.js
,获取输入文件路径、输出文件路径和格式、插件列表等信息。 - 模块解析:Rollup 解析输入文件及其依赖,通过插件(如
@rollup/plugin-node-resolve
)找到所有需要打包的模块。 - 模块转换:将模块转换为统一的 ES6 格式,便于后续处理。如果模块是 CommonJS 格式,会使用
@rollup/plugin-commonjs
插件进行转换。 - 依赖图生成:Rollup 会生成一个模块依赖图,确定模块的引用顺序。
- 打包输出:根据配置文件中的输出选项,将转换后的模块输出为指定格式的文件。例如,输出格式为 ES5 时,对应的输出将按照 ES5 的规范进行。
解析示例
假设有一个简单的项目结构如下:
src/
|- index.js
|- utils.js
index.js
引入了 utils.js
:
// src/index.js
import utils from './utils';
utils.greet();
// src/utils.js
export function greet() {
console.log('Hello, World!');
}
在 rollup.config.js
中配置 Rollup:
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true
})
]
};
运行打包命令:
npx rollup -c
Rollup 会解析 index.js
和 utils.js
,生成依赖图,并输出为 dist/bundle.js
文件。
转换示例
如果项目使用了 CommonJS 模块,并且需要转换为 ES6 模块,可以在配置文件中添加 @rollup/plugin-commonjs
插件:
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
commonjs({
include: /node_modules\/(.*)/,
exclude: /node_modules\/(@babel\/runtime)/
})
]
};
运行打包命令后,Rollup 会将 CommonJS 模块转换为 ES6 模块,生成最终的打包文件。
输出示例
假设需要输出为 AMD 格式,可以在 rollup.config.js
中配置输出格式为 amd
:
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'amd'
},
plugins: [
commonjs({
include: /node_modules\/(.*)/,
exclude: /node_modules\/(@babel\/runtime)/
})
]
};
运行打包命令后,Rollup 会输出为 AMD 格式的文件。
通过上述步骤,Rollup 可以高效地处理前端模块化开发中的各种需求,生成符合不同环境要求的打包文件。
Rollup应用实例 真实项目的打包案例假设有一个真实项目,包含以下文件结构:
src/
|- index.js
|- utils.js
|- components/
|- Button.js
|- Input.js
|- App.js
项目中使用了 ES6 模块、CommonJS 模块和第三方库 lodash
。index.js
是入口文件,并引入了 utils.js
和 components/App.js
。
入口文件 src/index.js
内容如下:
// src/index.js
import utils from './utils';
import App from './components/App';
utils.greet();
console.log(App);
utils.js
内容如下:
// src/utils.js
export function greet() {
console.log('Hello, World!');
}
App.js
内容如下:
// src/components/App.js
import _ from 'lodash';
export default {
render() {
console.log(_.map([1, 2, 3], n => n * 2));
}
};
在 rollup.config.js
文件中配置 Rollup 的打包规则:
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import terser from '@rollup/plugin-terser';
import env from '@rollup/plugin-env';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [
resolve({
preferBuiltins: true
}),
commonjs({
include: /node_modules\/(.*)/,
exclude: /node_modules\/(@babel\/runtime)/
}),
terser({
compress: true
}),
env()
]
};
插件使用说明
- @rollup/plugin-node-resolve:解析模块路径。
- @rollup/plugin-commonjs:将 CommonJS 模块转换为 ES 模块。
- @rollup/plugin-terser:压缩代码,减少文件大小。
- @rollup/plugin-env:注入环境变量。
运行打包命令:
npx rollup -c
打包后的 dist/bundle.js
文件将包含所有模块,并且代码会被压缩,环境变量也会被注入。
问题1:依赖模块找不到
问题描述:打包时,某些依赖模块找不到。
解决方法:确保 @rollup/plugin-node-resolve
插件已正确配置。检查依赖模块路径是否正确。例如,如果使用了第三方库 lodash
,确保它已安装在 node_modules
目录下。
问题2:输出格式不正确
问题描述:打包后的文件格式不符合预期。
解决方法:检查 rollup.config.js
中的 output.format
选项是否设置正确。例如,如果需要输出为 AMD 格式,应将 format
设置为 'amd'
。
问题3:代码压缩失败
问题描述:启用 @rollup/plugin-terser
插件后,代码未被压缩。
解决方法:检查 terser
插件配置中的 compress
选项是否设置为 true
。例如:
terser({
compress: true // 确保压缩
})
问题4:环境变量未注入
问题描述:启用 @rollup/plugin-env
插件后,环境变量未注入。
解决方法:确保在命令行中设置了环境变量,例如:
export NODE_ENV=production
npx rollup -c
问题5:模块转换失败
问题描述:使用 @rollup/plugin-commonjs
插件转换 CommonJS 模块失败。
解决方法:检查 commonjs
插件配置中的 include
和 exclude
选项是否正确。例如:
commonjs({
include: /node_modules\/(.*)/, // 包含的模块
exclude: /node_modules\/(@babel\/runtime)/ // 排除的模块
})