Rollup打包工具

1,328 阅读7分钟

一、概述

Rollup也是一款es moudle的打包器,也可将项目中的一些小模块打包成整块的代码。从而使划分的模块可以更好的运行在浏览器环境或者nodejs环境。Rollup与Webpack作用类似,但Rollup要小巧的多。webpack在配合插件情况下几乎可以完成前端中绝大多数工作。Rollup仅仅是一个ESM的打包器,并没有其他额外功能Rollup并不支持类似HMR这种高级功能Rollup诞生的目的并不是要与webpack全面竞争,他的初衷只是希望提供一个充分利用ESM各项特性的高效打包器(充分利用ESM各项特性构建出结构比较扁平、性能比较出众的类库)。

二、快速上手

准备工作: image.png 安装:yarn add rollup --dev
安装后rollup会在node_modules的bin目录下为我们提供一个cli程序,可以通过cli去使用打包。
运行:yarn rollup

在不传递任何参数的情况下rollup会打印出帮助信息。 在开始就提示我们rollup的正确用法了,需要通过参数去指定打包入口文件image.png 运行:yarn rollup ./src/index.js


此处若报错情况:意思是我们需要指定代码输出格式。即希望把esm的代码转换后以什么格式输出。 image.png 解决:yarn rollup ./src/index.js --format iife(自调用函数这样的格式)


打包成功: image.png
我们还可以用 --file 方式去指定打包输出路径,打包结果就会输出到文件当中。
命令:yarn rollup ./src/index.js --file dist/bundle.js image.png 打包输出的结果几乎没有任何多余的代码,就是把我们打包过程中各个模块,按照模块的依赖顺序先后拼接到一起。在输出结果中只会去打包用到的部分,对于未引用的都没有去输出。这是因为rollup默认会开始 tree shaking去优化我们打包的结果,tree shaking的概念最早也是在rollup当中提出的。

三、Rollup 配置文件

在项目中添加rollup.config.js文件。这个文件同样是运行在node环境当中,rollup自身会额外处理这个配置文件,所以这里可以直接使用es module。 image.png

四、Rollup 使用插件

Rollup 自身功能就只是es moudle的合并打包,如果项目有更高级的需求,如需要去加载其他类型的资源模块、要在代码中导入commonjs模块、编译ECMAScript新特性这些需求,rollup同样支持使用插件的方式去扩展。插件是Rollup 唯一的扩展途径
举例:rollup-plugin-json 插件的使用
安装:yarn add rollup-plugin-json --dev
image.png 打包: yarn rollup --config,查看结果可发现被我们使用的被打包进来了,未使用的被tree shaking掉了。 image.png

五、Rollup 加载 NPM 模块

Rollup默认只能按照文件路径方式去加载本地的模块,对于node_modules中的第三方模块并不能像webpack一样直接去通过导入对象名称导入对应模块。为了解决这个差异,rollup官方给出了一个rollup-plugin-node-resolve插件,rollup-plugin-node-resolve插件可以在代码当中直接使用导入模块名称去导入模块

安装:yarn add rollup-plugin-node-resolve --dev 使用: image.png 打包:可以发现lodash确实被打包到输出文件当中了。 image.png 之所以使用lodash-es版本,是因为rollup只能去处理es moudle模块。

六、Rollup 加载 CommonJS 模块

Rollup只es module模块的打包,不支持CommonJS 模块打包。但是官方npm 大部分是使用commonjs模式导出的,所以需要兼容插件:rollup-plugin-commonjs
安装:yarn add rollup-plugin-commonjs --dev image.png 打包结果:打包成功! image.png

七、Rollup 代码拆分

rollup最新版本已经可以支持代码拆分了,可以使用动态导入(dynamic imports)的方式去实现模块按需加载。rollup内部会自动处理代码拆分。 image.png 打包结果报错:iife输出格式不支持代码拆分。原因:iife(自执行函数)是把所有的模块都放到同一个模块当中,他并没有向webpack一样有些引导代码,所以无法实现代码拆分。想使用代码拆分就必须使用AMD或者COMMONJS等其他的标准。浏览器环境只能使用AMD标准 image.png AMD输出标准打包!报错原因:代码拆分需要输出多个文件,这里就不能使用file的配置方式,因为file是指定单个文件输出的文件名,需要多个文件输出,可以使用dir参数。 image.png 配置dir,并且再次打包 image.png 成功,并且分了两个模块文件!一个入口bundle和一个动态导入对应的bundle,他们都是采用AMD标准去输出的。 image.png

八、Rollup 多入口打包

rollup也能实现多入口打包,对于不同入口当中的公共部分也会自动提取到单个文件当中,作为独立的bundle。
可以使用input数组或者对象两种方式: image.png 打包后得到三个文件,分别是两个不同入口文件模块和一个提取出来的公共模块。 image.png 另外需注意对于amd这种输出格式的js文件我们不能直接去引用到页面上,必须要通过实现amd的标准库去加载。 image.png 打包结果正常加载并且工作了。

九、Rollup 选用原则

rollup优势

  1. 输出结果更加扁平,执行效率更高
  2. 自动移除未引用代码
  3. 打包结果依然完全可读 rollup缺点
  4. 加载非ESM的第三方模块比较复杂,需要配置一些插件
  5. 模块最终都被打包到一个函数中,无法实现HMR热替换体验
  6. 浏览器环境中,代码拆分依赖AMD库 总体来说:当我们正开发应用程序,肯定要大量引用第三方模块、使用HMR热更新功能提升开发体验、功能一旦大就需要分包,rollup不适合。若开发的是一个js框架或者类库,极少代码中去依赖第三方模块,如react、vue等框架或者类库都是使用rollup作为打包器,而不是webpack。
    webpack 大而全,rollup 小而美!

十、Parcel -- 零配置前端打包器

创建一个空项目,yarn init初始化项目。yarn add parcel-bundler --dev安装parcel。
打包命令:yarn parcel src/index.html yarn parcel + 打包入口文件。

1.parcel不仅帮我们打包了应用,还同时开启了一个开发服务器。

当修改源代码并保存后,浏览器会自动刷新,执行最新打包结果。 image.png

2.HMR体验

image.png

3.自动安装依赖

只需要正常导入,并且使用即可。当保存过后parcel会自动安装我们刚刚导入的这个模块,极大程度避免了手动操作。 image.png

4.支持加载其他类型的资源模块

相比于其他打包器,parcel中加载任意资源的模块依然是零配置的。并未使用任何插件和loader,报错过后立即生效! image.png

5.支持动态导入,若使用了动态导入会自动拆分代码

image.png

6.以生产环境模式打包

yarn parcel build src/index.html 对于相同体量的项目打包,parcel比webpack快很多,因为parcel内部使用的是多进程同时去工作,充分发挥了多核cpu的性能。webpack中也可以使用happypack的插件去实现这一点。 image.png 打包后代码也都被压缩了,样式代码也都单独提取到单个文件当中了。

7.总结

parcel 是2017年发布的,出现原因是当时webpack使用时过于繁琐、官方文档也不清晰明了。parcel 完全零配置、构建速度快。虽然parcel 很好,但是绝大多是还是使用webpack打包,原因:

  1. webpack有更好的生态,扩展丰富,容易定位问题
  2. 随着发展webpack越来越好用