Skip to main content

rollup.js 初体验

· 4 min read
ulli

最近,我准备基于 rollup 编写一个 @draculabo/alias 辅助库,并将其发布到 npm 上。为了兼容不同模块(例如 CommonJS 和 ESModule),可以使用打包器轻松地将代码分别编译成这些不同的模块格式。

刚好,rollup 3 官方版本已发布,我将使用它来尝试。

为什么不是 Webpack?

Rollup 的特点是支持 ES6 模块和代码 Tree-shaking。这些特性在 Webpack 中同样有支持。除此之外,Webpack 还支持热模块替换、代码分割、静态资源导入等更多功能。当需要开发应用时,优先选择 Webpack。但是,如果只需要打包出一个简单的 Bundle 包,而且是基于 ES6 模块开发的,则可以考虑使用 Rollup。相比于 Webpack,Rollup 有更少的功能和更简单的 API。这也是我们在打包类库时选择 Rollup 的原因。当然,我准备编写的工具包正是这样的项目。

支持打包的模块格式

目前常见的模块规范有:

  • IFFE:使用立即执行函数实现模块化 例:(function(){})()

  • CJS:基于 CommonJS 标准的模块化

  • AMD:使用 Require 编写

  • ESM:ES 标准的模块化方案 ( ES6 标准提出 )

  • UMD:兼容 CJS 与 AMD、IFFE 规范

以上 Rollup 都是支持的。

使用

官方提供了一篇创建你的第一个 bundle的文章。不过英文文档阅读难度较大,而且通过命令方式+选项的方式打包不是我们想要的工程化方式。

配置文件

因此,可以通过 rollup.config.js 配置文件来打包,然后通过rollup -c 命令进行打包。以下是一个示例文件:

rollup.config.js
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs',
},
}

运行 rollup -c 命令就会将 main.js 中所引用到的 js 代码,按照 commonjs 的方式编写到 bundle.js 文件中,如下所示:

bundle.js
'use strict'

var foo = 'hello world!'

function main() {
console.log(foo)
}

module.exports = main

更多的情况下,需要同时打包多个模块格式的包。此时,在 output 属性中传入一个由多个输出对象组成的数组,例如:

rollup.config.js
export default {
input: 'src/main.js',
output: [
{
file: 'bundle.cjs',
format: 'cjs',
},
{
file: 'bundle.mjs',
format: 'esm',
},
],
}

便会生成 bundle.cjs, bundle.mjs 两种不同的模块格式的文件。同时在 package.json 中,指定对应模块路径,在引入时,便会根据当前的项目环境去选择导入哪个模块。

package.json
{
"main": "bundle.cjs",
"module": "bundle.mjs"
}

结合 rollup 插件使用

更多情况下,需要配置 Rollup 插件来使用。官方插件地址是rollup/plugins

例如,可以使用 rollup-plugin-esbuild 插件来加快打包速度,同时可以借助 @rollup/plugin-babel 使用 babel,将代码转换成兼容性更强的。

以下是 rollup + 插件的配置示例,来源于antfu/utils/rollup.config.js,同时也是我工具包的配置。

rollup.config.js
import esbuild from 'rollup-plugin-esbuild'
import dts from 'rollup-plugin-dts'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import alias from '@rollup/plugin-alias'

const entries = ['src/index.ts']

const plugins = [
alias({
entries: [{ find: /^node:(.+)$/, replacement: '$1' }],
}),
resolve({
preferBuiltins: true,
}),
json(),
commonjs(),
esbuild({
target: 'node14',
}),
]

export default [
...entries.map(input => ({
input,
output: [
{
file: input.replace('src/', 'dist/').replace('.ts', '.mjs'),
format: 'esm',
},
{
file: input.replace('src/', 'dist/').replace('.ts', '.cjs'),
format: 'cjs',
},
],
external: [],
plugins,
})),
...entries.map(input => ({
input,
output: {
file: input.replace('src/', '').replace('.ts', '.d.ts'),
format: 'esm',
},
external: [],
plugins: [dts({ respectExternal: true })],
})),
]

以下是对应的 npm 安装命令

pnpm i -D rollup @rollup/plugin-alias @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-node-resolve rollup-plugin-esbuild rollup-plugin-dts

更多 Rollup 的使用信息,可以参见官方文档以及其他使用 Rollup 打包的开源项目。

类似工具

除了 Rollup 之外,还有其他打包工具,例如Webpack.jsesbuildParcel.js

不过,对于打包类库而言,并不要求过于强大的性能,只需要一个相对简单的配置就足以胜任,而 Rollup 正是这样的打包工具。

相关文章

【实战篇】最详细的 Rollup 打包项目教程

一文带你快速上手 Rollup

Loading Comments...