[譯] 同中有異的 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前端後端產品設計 等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃

相關文章
相關標籤/搜索