[译] 同中有异的 Webpack 与 Rollup

同中有异的 Webpack 与 Rollup

本周,Facebook 将一个很是大的 pull request 合并到了 React 主分支。这个 PR 将 React 当前使用的构建工具替换成了 Rollup。这让许多人感到不解,纷纷在推特上提问:“为何大家选择 Rollup 而不选择 Webpack 呢?”1 2 3前端

有人问这个问题是很正常的。Webpack 是如今 JavaScript 社区中最伟大的成功传奇之一,它有着数百万/月的下载量,驱动了成千上万的网站与应用。它有着巨大的生态系统、众多的贡献者,而且它与通常的社区开源项目不一样——它有着意义非凡的经济支持react

相比之下,Rollup 是那么的微不足道。可是,除了 React 以外,Vue、Ember、Preact、D三、Three.js、Moment 等众多知名项目都使用了 Rollup。为何会这样呢?为何这些项目不使用你们一致承认的 JavaScript 模块打包工具呢?android

这两个打包工具的优缺点

Webpack 由 Tobias Koppers 在 2012 年建立,用于解决当时的工具不能处理的问题:构建复杂的单页应用(SPA)。尤为是它的两个特色改变了一切:webpack

  1. 代码分割能够将你的 app 分割成许多个容易管理的分块,这些分块可以在用户使用你的 app 时按需加载。这意味着你的用户能够有更快的交互体验。由于访问那些没有使用代码分割的应用时,必需要等待整个应用都被下载并解析完成。固然,你也能够本身手动去进行代码分割,可是……总之,祝你好运。
  2. 静态资源的导入:图片、CSS 等静态资源能够直接导入到你的 app 中,就和其它的模块、节点同样可以进行依赖管理。所以,咱们不再用当心翼翼地将各个静态文件放在特定的文件夹中,而后再去用脚本给文件 URL 加上哈希串了。Webpack 已经帮你完成了这一切。

而 Rollup 的开发理念则不一样:它利用 ES2015 模块的巧妙设计,尽量高效地构建精简且易分发的 JavaScript 库。而其它的模块打包器(包括 Webpack在内)都是经过将模块分别封装进函数中,然将这些函数经过能在浏览器中实现的 require 方法打包,最后依次处理这些函数。在你须要实现按需加载的时候,这种作法很是的方便,可是这样作引入了不少无关代码,比较浪费资源。当你有不少模块要打包的时候,这种状况会变得更糟糕ios

ES2015 模块则启用了一种不一样的实现方法,Rollup 用的也就是这种方法。全部代码都将被放置在同一个地方,而且会在一块儿进行处理。所以获得的最终代码相较而言会更加的精简,运行起来天然也就更快。你能够点击这儿亲自试试 Rollup 交互式解释器(REPL)git

但这儿也存在一些须要权衡的点:代码分割是一个很棘手的问题,而 Rollup 并不能作到这一点。一样的,Rollup 也不支持模块热替换(HMR)。并且对于打算使用 Rollup 的人来讲,还有一个最大的痛点:它经过插件处理大多数 CommonJS 文件的时候,一些代码将没法被翻译为 ES2015。而与之相反,你能够把这一切的事所有放心交给 Webpack 去处理。github

那么我到底应该选用哪个呢?

到目前为止,咱们已经清晰地了解了这两个工具共存而且相互支撑的缘由 — 它们应用于不一样的场景。那么,如今这个问题的答案简单来讲就是:web

在开发应用时使用 Webpack,开发库时使用 Rollupjson

固然这不是什么严格的规定——有不少的网站和 app 同样是使用 Rollup 构建的,同时也有不少的库使用 Webpack。不过,这是个很值得参考的经验之谈。后端

若是你须要进行代码分割,或者你有不少的静态资源,再或者你作的东西深度依赖 CommonJS,毫无疑问 Webpack 是你的最佳选择。若是你的代码基于 ES2015 模块编写,而且你作的东西是准备给他人使用的,你或许能够考虑使用 Rollup。

对于包做者的建议:请使用 pkg.module

在很长一段时间里,使用 JavaScript 库是一件有点风险的事,由于这意味着你必须和库的做者在模块系统上的意见保持一致。若是你使用 Browserify 而他更喜欢 AMD,你就不得不在 build 以前先强行将二者粘起来。通用模块定义(UMD)格式对这个问题进行了 部分 的修复,可是它没有强制要求在任何场景下都使用它,所以你没法预料你将会遇到什么坑。

ES2015 改变了这一切,由于 importexport 就是语言规范自己的一部分。在将来,再也不会有如今这种模棱两可的状况,全部东西都将更加无缝地配合工做。不幸的是,因为大多数浏览器和 Node 还不支持 importexport,咱们仍然须要依靠 UMD 规范(若是你只写 Node 的话也能够用 CommonJS)。

如今给你的库的 package.json 文件增长一个 "module": "dist/my-library.es.js" 入口,可让你的库同时支持 UMD 与 ES2015。这很重要,由于 Webpack 和 Rollup 都使用了 pkg.module 来尽量的生成效率更高的代码——在一些状况下,它们都能使用 tree-shake 来精简掉你的库中未使用的部分。

了解更多有关 pkg.module 的内容请访问 Rollup wiki

但愿这篇文章能让你理清这两个开源项目之间的关系。若是你还有问题,能够在推特联系rich_harrisrollupjsthelarkinn。祝你打包快乐!

感谢 Rich Harris 写了这篇文章。咱们坚信开源协做是共同促进 web 技术前进的重要动力。

没有时间为开源项目作贡献?想要以其它方式回馈吗?欢迎经过 Open Collective 进行捐赠,成为 Webpack 的支持者或赞助商。Open Collective 不只会资助核心团队,并且还会资助那些贡献出空闲时间帮助咱们改进项目的贡献者们。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOSReact前端后端产品设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划

相关文章
相关标签/搜索