Rollup
Rollup 是一款 JavaScript 模块打包器,它可以将一些零散的 JavaScript 模块打包成一个或多个具有高度优化的 bundle。
与其他打包器如 webpack 和 Parcel 不同,Rollup 更适用于构建 JavaScript 库或组件,因为它能够生成一个纯净的、可重用的模块化代码。
Rollup 采用 ES6 模块和 Tree-shaking 技术,可以消除未使用的代码,从而减小 bundle 的大小。这使得它生成的 bundle 更小、更快、更易于维护和优化,特别适合于在浏览器环境中使用。
Rollup 的配置简单、易于使用,支持多种插件和自定义插件,可以满足各种需求。如果你想构建一个高效、可维护、可重用的 JavaScript 库或组件,那么 Rollup 是一个不错的选择。
Usage
使用 Rollup 打包库也非常简单
install
npm i rollup -D
config
创建 Rollup 配置文件 rollup.config.js
// rollup.config.js
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'umd'
}
}
build
npx rollup --config rollup.config.js
此配置将 src/index.js
打包为一个 UMD 格式的 bundle,并输出到 dist/bundle.js
。
要使用插件,请在配置文件中导入插件并将其添加到 plugins
中。例如,要使用 Babel 插件将 ES6 代码转换为 ES5 代码:
npm i rollup-plugin-babel -D
// rollup.config.js
import babel from 'rollup-plugin-babel';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'umd'
},
plugins: [
babel({
exclude: 'node_modules/**'
})
]
}
这将在打包时使用 Babel 插件来转换你的代码。
Features
Rollup 有非常多的优秀的特性
Tree-Shaking
Tree-Shaking
是一种去除 JavaScript 代码中未使用部分的技术,可以减小 bundle
的大小
// math.js
export function square(x) {
return x * x;
}
// 打包后,这段代码不会出现在 bundle 中
export function cube(x) {
return x * x * x;
}
// index.js
import { square } from './math.js';
console.log(square(4));
在这个示例中,math.js
导出了两个函数 square
和 cube
,而 index.js
只使用了 square
函数。如果使用 Rollup 和 Tree-Shaking 技术打包这些文件,那么输出的 bundle 将只包含 square
函数和其依赖的代码,而 cube
函数和其依赖的代码将被移除。
Multiple outputs
Rollup 也可以生成多种输出格式,包括 CommonJS、AMD、ES6 模块和 UMD。在 Rollup 配置文件的 output
属性中指定 format
选项即可。例如,要生成一个 CommonJS 格式的输出文件和一个 ES6 模块格式的输出文件,可以这样配置:
// rollup.config.js
export default {
input: 'src/index.js',
output: [
{
file: 'dist/bundle.cjs.js',
format: 'cjs'
},
{
file: 'dist/bundle.esm.js',
format: 'es'
}
]
}
这将生成一个 CommonJS 格式的输出文件 dist/bundle.cjs.js
和一个 ES6 模块格式的输出文件 dist/bundle.esm.js
。同时也可以使用其他格式,如 AMD 和 UMD。注意,当使用 UMD 格式时,需要指定 name
选项来指定全局变量的名称。例如:
// rollup.config.js
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary'
}
}
这将生成一个 UMD 格式的输出文件 dist/bundle.umd.js
,并将全局变量命名为 MyLibrary
,使得它可以在浏览器和 Node.js 等环境中使用。
Code Splitting
在 Rollup 中,可以使用动态导入语法来实现原生的代码分割。动态导入语法与常规导入语法类似,只是将 import
关键字替换为 import()
函数。
// rollup.config.js
export default {
input: "src/index.js",
output: {
dir: "dist",
},
}
// src/foo.js
export default 1;
// src/index.js
export default function () {
// 分割 foo.js
import("./foo.js").then(({ default: foo }) => console.log(foo));
}
最终打包,./foo.js
会被单独的分割开
Powerful plugins
Rollup 的插件系统非常灵活,可以满足各种需求。Rollup 的插件分为两种类型:转换插件和输出插件。转换插件用于处理源代码,例如将 ES6 代码转换为 ES5 代码、将 CSS 文件转换为 JavaScript 代码等。输出插件用于生成输出文件,例如将 JavaScript 代码写入文件、将代码发送到服务器等。
Rollup 的插件生态非常丰富,有许多优秀的插件可供使用。以下是一些常用的 Rollup 插件:
@rollup/plugin-node-resolve
:用于解析 Node.js 模块导入语法和第三方模块的依赖关系。使用这个插件可以方便地将 Node.js 模块和第三方模块打包到你的 bundle 中。@rollup/plugin-commonjs
:用于将 CommonJS 模块转换为 ES6 模块。使用这个插件可以方便地将 CommonJS 模块打包到你的 bundle 中。rollup-plugin-babel
:用于将 ES6+ 代码转换为 ES5 代码。使用这个插件可以方便地在 Rollup 中使用 Babel。rollup-plugin-terser
:用于压缩 JavaScript 代码。使用这个插件可以减小输出文件的大小,提高页面加载速度。rollup-plugin-sass
:用于将 Sass 文件转换为 CSS 文件。使用这个插件可以方便地在 Rollup 中使用 Sass。rollup-plugin-postcss
:用于将 CSS 文件转换为 JavaScript 代码。使用这个插件可以方便地在 Rollup 中使用 PostCSS。rollup-plugin-image
:用于将图片转换为 JavaScript 代码。使用这个插件可以方便地在 Rollup 中使用图片。rollup-plugin-json
:用于将 JSON 文件转换为 JavaScript 代码。使用这个插件可以方便地在 Rollup 中使用 JSON。
以上插件只是 Rollup 插件生态中的一部分,还有许多其他优秀的插件可供选择。在使用插件时,需要注意不要过度依赖插件,以免增加 bundle 的大小和构建时间。同时,也需要选择适合自己项目的插件,以免出现兼容性和性能问题。
总体而言,Rollup 是非常棒的库打包工具
unbuild
unbuild 也是 js
库打包工具,相比 rollup
有更好的开发体验 🥰
Usage
unbuild 的使用就更简单了
install
npm i unbuild -D
demo
创建 src/index.ts
:
export const log = (...args) => { console.log(...args) }
更新 package.json
:
{
"type": "module",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
]
}
build
npx unbuild
打包完成了
当然它也支持配置文件 👉 unbuild/configuration,但大多数情况下你是不需要的
Features
Optimized bundler
unbuild 基于Rollup,集成了 Rollup 生态中非常优秀的插件,开箱即用的支持 typescript
,并允许生成commonjs
和esmodule
格式和类型声明。
这意味着不需要你手动一个个安装插件,配置,调试后才可以进行库开发。
简单查看源码也可以发现内置了很多插件。
这些插件直接用社区第三方的,也有自己魔改的 (在 src/builder/plugins 中)。
值得一提的是,这里用了 esbuild 来转换 js
代码,比原生 Rollup 还要快。
Automated config
unbuild 可以自动智能从 package.json
中推断出打包的入口和配置。这意味着大多数情况下,我们甚至不需要配置文件就可以进行正确地打包。
简单查看源码也可以发现,解析预设时未发现预设会回滚到自动预设
而 autoPreset
会递归扫描 src
源码目录获取所有源文件路径,同时结合 package.json
推断出 Entries
入口。
其中 inferEntries
中最有意思的是对 package.json
中 bin
的处理 👇
有了这个,如果我们开发 cli
,就不需要单独配置,很 nice
🥰
Bundleless build
集成了 mkdist ,一个轻量的文件转换器。有点像 webpack
的 loader
,用来给文件进行预处理的。
而且 mkdist 可以保持原有目录文件的结构,也支持 vue
的 sfc
组件,还能 copy
静态文件。
值得一提的是,我为 copy
静态文件部分提过 pr
,用流来跑 copy
,支持大型文件,速度很快。
具体可见 👉 perf: copy raw files with stream by markthree · Pull Request #70 · unjs/mkdist
当然携带大型文件到 npm
库中是不推荐的。
Passive watcher
stub
插桩,是我最喜欢的功能。
传统的打包工具,在开发环境采用监听模式时,每改动一次源码就需要打包一次。
例如下边用 Rollup,你会发现每次我保存源文件,都得重新打包一次。
这在小项目开发当然无所谓,但是当我们进行 monorepo
开发时就完蛋了。
可能我们简单改其中一行代码,就会触发多个包一起打包,人直接麻了 🤕
而在 unbuild
中,我们可以使用插桩 👇
npx unbuild --stub
你会发现我们的进程断开了,然后生成了带有 jiti 的 bundle
。
这时我们其实就可以直接使用开发环境的代码了,因为 jiti 可以动态的执行 js
或者 ts
源码,不需要监听模式 🥰
这也意味着我们在写 monorepo
时,只需要运行一次 stub
即可,不会触发重新打包。
Untype Generator
集成了 untyped,可以通过 markdown
和配置对象生成类型。
Secure builds
自动检查各种构建问题,例如潜在的丢失和未使用的依赖项。
cli
输出还包括了大小和导出,以进行快速检查。
尾声
后边我可能会介绍如何正确打包库,也欢迎关注 👇
或者关注我的开箱即用的 node 库模板 👉 node-lib-starter
评论(0)