Webpack 和 Rollup:一样但又不同

Posted 小生方勤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Webpack 和 Rollup:一样但又不同相关的知识,希望对你有一定的参考价值。


最近在看 Vue 源码的时候发现一个新的打包工具 Rollup.js,之前没有听说过这个工具,也不了解 Rollup.js 相比于常用的打包工具 webpack 有什么异同和优势,随后查了一下了解到 Vue,React,D3,Three.js,Moment 源码里都有它的身影,Rollup 到底什么?这篇文章带你走进 Rollup 的世界。


因为笔者习惯在学习新东西的时候,先从已经了解掌握类似功能的东西出发,寻找差异点,由浅入深,渐进学习,故此篇先从耳熟能详的 webpack开始讲起。

webpack 的几大特性

代码拆分


在 webpack 中,代码分离是最引人注目的特性之一。 因为对于前端而言,资源包与依赖文件体积过大,将会直接影响性能。 尤其是在移动互联网时代,大文件的加载问题也会使得用户体验直线下降,所以如何拆分代码,按需加载是目前很多应用所面临的问题。
在 webpack 的实现中,通过代码拆分功能将大的资源和依赖文件进行拆解,从而使得当用到某些资源时,能够就只加载这些文件,而避免加载无用资源,使用合理的话,会极大影响加载时间,提示用户体验。


目前 webpack 常用的代码分离方法有三种:

  • 入口起点:使用 entry 配置手动地分离代码。

  • 防止重复:使用 SplitChunksPlugin 去重和分离 chunk。

  • 动态导入:通过模块中的内联函数调用来分离代码。


静态模块打包



在 webpack 的官网上写道,webpack是一个现代 javascript 应用程序的静态模块打包器,能够 打包所有的资源,脚本,图片,样式表等一系列内容均可打包,这也是很多人选择使用webpack基本诉求。


在webpack实现各类资源打包时,由于webpack 自身只理解 JavaScript,所以对于除了 JavaScript 之外的资源需要使用 loader 让 webpack 能够去处理。 loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块 ,然后就可以利用 webpack 的打包能力,对它们进行处理。

本质上,webpack 的 loader 可以将所有类型的文件,都转换为应用程序的依赖图和最终的打包结果可以直接引用的模块。 目前在官网提供了很多的 loader,当然你有兴趣可以写一个自己的 loader,通过自定义加载去使用。


插件机制


webpack中,插件可以完成更多 loader 不能完成的功能,webpack 内部 以插件的形式提供了灵活强大的自定义 api 功能,其本身暴露了 webpack 在运行的整个生命周期钩子函数,从而方便注册插件和使用插件,可见 webpack 的插件是直接对整个构建过程其作用。

Rollup 的特点

JavaScript 模块打包器


Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如一些后台语言的编译功能,将代码压缩成一个 library 或应用程序,Rollup 对代码模块使用新的 ES6 版本中的标准化格式,并非是 CommonJS 和 AMD这种自定义的解决方案。


Tree-shaking


Tree-shaking, 也被称为 "live code inclusion" ,指清除在项目中没有实际 用到的冗余代码 相比于Webpack和Browserify使用的CommonJS 模块机制,Rollup 中使用 ES6 版本中的Modules标准格式编写模块代码使得Rollup对代码做静态分析和从模块中删除无用的代码时更加高效,更容易。


Vue 的作者尤雨溪在知乎里回答,关于 Rollup 之所以能高效的用Tree-shaking 来消除无用的代码主要为以下四个原因。
  1. import 只能作为模块顶层的语句出现,不能出现在 function 里面或是 if 里面。

  2. import 的模块名只能是字符串常量。

  3. 不管 import 的语句出现的位置在哪里,在模块初始化的时候所有的 import 都必须已经导入完成。

  4. import binding 是 immutable 的,类似 const。比如说你不能 import { a } from ‘./a’ 然后给 a 赋值个其他什么东西。


Rollup 官方对 Rollup.js 和 webpack 怎么看?


Rollup 已被许多主流的 JavaScript 库使用,也可用于构建绝大多数应用程序。但是 Rollup 还不支持一些特定的高级功能,尤其是用在构建一些应用程序的时候,特别是代码拆分和运行时态的动态导入。如果你的项目中更需要这些功能,那使用 Webpack 可能更符合你的需求。 与Webpack 偏向于应用打包的定位不同, rollup.js 更专注于 Javascript 类库打包

Rollup 和 Webpack 怎么选

先看一下目前使用 webpack 和 rollup 的一些应用简单分类。


Webpack

Rollup

vue-cli, create-react-app 各类应用脚手架

react,vue,three.js,D3,moment


Rollup 作者曾在一篇文章里分析了 Webpack 和 Rollup 的不同之处,并且总结到 Webpack 适合在应用层级 Web App 上使用,而Rollup 更适合使用在独立的 JavaScript 模块库上。

Use Webpack for apps, and Rollup for libraries

但这不是一个绝对的规则,事实上有许多网站和应用程序使用 Rollup 构建,同样的也有大量的类库使用了 webpack 构建。
对于打包工具的选择,这时候还是要看你具体的需求, 如果你的诉求是需要代码拆分,或者你有很多静态资源需要处理,再或者你构建的项目需要引入很多 CommonJS 模块的依赖,那应该选择 webpack 。 但是如果你的代码库是基于 ES6 模块的,而且希望你写的代码能够被其他人直接使用,你更需要的打包工具可能是 Rollup。

NOT THE END

若觉文章尚可,何妨关注小生。

第一时间接收优秀文章(发送“交流加群”即可进前端交流群

在看即是欢喜

以上是关于Webpack 和 Rollup:一样但又不同的主要内容,如果未能解决你的问题,请参考以下文章

weboack的搭建

weboack的搭建

weboack的搭建

如何定量分析前端主流的构建工具(Webpack/Rollup/Parcel/Browserify+Gulp)?

一次性支持Webpack,Parcel和Rollup的最佳方法是什么?

使用roolup构建你的lib