前端構建工具的未來

本文作者系 360 奇舞團前端開發工程師

本文爲翻譯
原文標題:The Future Of Frontend Build Tools
原文作者:Alexander Joseph
原文鏈接:https://www.smashingmagazine.com/2022/06/future-frontend-build-tools/

因此,用戶可以享受能力更強、功能更豐富的應用程序,通過代碼分割、緩存、預取和其他資源優化技術保持性能 -- 有些應用程序甚至能夠離線工作。

今天,前端工具爲我們提供瞭如此多的東西,以至於很難想象曾經有一段時間甚至根本不需要它。回憶一下,可以幫助我們理解我們是如何走到今天的。

過去

在前端應用程序變得像今天這樣複雜之前,所有的 JavaScript 都是用來爲其他簡單的 HTML 文檔添加基本的交互性 -- 類似於 Adobe 的 Flash 的使用方式。

當時沒有複雜的 "JavaScript-heavy" 應用,因此不需要任何工具來更好地編寫和發佈 JavaScript,但這種情況不會一直存在。

隨着時間的推移,我們開始在網絡上創造更多的用戶體驗,我們從更多的靜態網頁轉向服務於用戶特定數據的高度動態網絡應用。這些應用程序比傳統的應用程序需要更多的 JavaScript,而使用 JavaScript 的侷限性也變得更加明顯。

在瀏覽器中加載 JavaScript 有兩種主要方式:一種是用腳本標籤引用 JavaScript 文件,另一種是在 HTML 中直接將 JavaScript 寫入腳本標籤。

<script src="my-javascript-file.js"></script>

<script>
    var a = 1;
    var b = 2;
    var result = a + b;
</script>

當你有大量的 JavaScript 需要加載時,這種對加載 JavaScript 的限制就會成爲一個瓶頸。同時加載許多 JavaScript 文件有瀏覽器的限制,而擁有一個巨大的 JavaScript 文件也有可維護性的問題(比如文件大小、範圍問題、命名空間衝突等等)。

我們想出了一些解決方案,如立即調用函數表達式(IIFEs),以幫助解決封裝和一些範圍問題,之後,我們獲得了在許多不同文件中編寫 JavaScript 的能力。然後,我們需要一種方法,將這些文件合併成一個文件,在瀏覽器中提供服務。

現在

由於能夠用 IIFEs 將我們的 JavaScript 分割成不同的文件,我們似乎只需要一種方法將這些文件串聯起來,並將一個文件傳送給瀏覽器。在這種需求下,Gulp、Grunt、Brocolli 等工具應運而生。然而,我們很快意識到,我們的想法可能有點太簡單了。

隨着我們的應用程序變得更加複雜,缺乏無用代碼消除、針對小更改的完全重建以及其他性能問題等問題讓我們意識到我們需要的不僅僅是串聯。這催生了更現代的打包工具,如 Webpack、Parcel 等。

隨着前端領域的進步步伐沒有放緩,我們已經開始觀察到現代構建工具的差距和問題。

一些主要的侷限性包括:

在 JavaScript 生態系統中,事物變化的速度往往讓人感到疲憊,但好處是社區能迅速發現問題並着手解決潛在的解決方案。我們的目標是提高前端工具的性能,新一代的構建工具正在開發中。

未來

由於當今主流構建工具的限制,出現了許多重新構想前端構建工具的嘗試,而且目前市面上有相當多的新型構建工具。

仔細觀察會發現,這些新工具似乎採取了兩種主要方法來解決這個問題(並不一定是相互排斥的):平臺的改變和範式的轉變,這兩者都受到了 Web 開發生態系統中的新進展的推動。

平臺的改變

傳統上,前端構建工具一直是使用 JavaScript,近年來也使用了 TypeScript 進行構建。這是有道理的,因爲 JavaScript 是 Web 的語言,使用相同的語言編寫 Web 構建工具可以更容易地讓更多人蔘與其中,並在這些工具周圍建立社區。然而,這種方法也存在固有的問題。

作爲一種高級語言,JavaScript 無法達到原生的性能水平。這意味着構建在該平臺之上的工具對其性能有限制。因此,爲了突破這一限制,新的構建工具正在構建在較低級別、本質上性能更高的語言(如 Rust)上。

像 Rust 和 Go 這樣的語言已經成爲編寫下一代構建工具的熱門選擇,它們非常強調性能。特別是 Rust,不僅因其性能而受歡迎,還因其令人印象深刻的開發者體驗而受歡迎在 Stack Overflow 開發者調查中連續六年被評爲 "最受喜愛的" 編程語言。

在談到用 Rust 構建 Rome(一個用於構建現代 JavaScript 應用程序的一體化工具鏈)的決定時,Jamie Kyle 說:

“許多其他人已經在我們面前傳達了 Rust 的性能、內存和安全優勢——讓我們說,每個曾經說過 Rust 很好的人都是正確的。然而,我們最擔心的是我們自己的生產力。[...] 然而,經過一些原型設計後,我們很快意識到我們實際上可能在 Rust 中更有效率”
Jamie Kyle in Rome Will Be Written In Rust

SWC 項目處於將 Rust 用於前端構建工具這一想法的最前沿。它現在正在爲 Next.js 的新編譯器、Deno、Parcel 等項目提供支持,其性能比其他現有構建工具高出多個數量級。

像 SWC 這樣的項目證明,隨着底層平臺的改變,構建工具的性能可以得到顯着提高。

範式的轉變

如今,典型的前端構建流程如下:您可以在許多不同的文件中編寫 JavaScript 模塊,然後運行一個命令,構建工具會收集這些模塊,將它們捆綁成一個單獨的模塊,將其轉換爲瀏覽器可理解的格式,並在瀏覽器中提供該文件。

爲了提高開發模式下的性能,許多需要較長時間才能完成的優化被省略,而是在打包生產應用程序時運行,這樣可以確保啓動開發服務器、在開發模式下運行應用程序並提高生產效率所需的時間儘可能短。

Unbundled Development 很棒。它解決了現有構建工具的一個主要問題:即使是微小的代碼更改,它們通常需要重新構建整個應用程序的部分,而隨着應用程序的增長,構建時間也越來越長,這失去了快速反饋——這是愉快的開發體驗所必需的。

有人可能想知道,如果 Unbundled Development 如此出色,爲什麼今天不成爲常態呢?Unbundled Development 纔開始受到關注有兩個主要原因:現代瀏覽器對於最新功能的兼容性和處理節點模塊導入的方式。

1. 現代瀏覽器的兼容性

Unbundled Development 由 ES 模塊 (ESM) 提供支持,它爲 JavaScript 帶來了標準化的模塊系統——在包括瀏覽器在內的多個運行時中得到原生支持。有了這個新功能,我們可以將我們的腳本標記標記爲模塊,因此可以使用我們都熟悉的import和關鍵字;export

ES 模塊已經存在了很長一段時間。儘管如此,我們只能開始將它用於 Unbundled Development 之類的事情,這主要是因爲它的標準化在網絡生態系統中的所有參與者中花費了很長時間。

在她關於 ES 模塊的文章中,關於 Mozilla Hacks,Lin Clark 說:

“ES 模塊爲 JavaScript 帶來了一個官方的、標準化的模塊系統。不過,這需要一段時間才能實現——將近 10 年的標準化工作。”
Lin Clark 在 ES Modules: A Cartoon Deep-Dive

瀏覽器支持與否的問題長期以來一直困擾着前端開發。這就是爲什麼我們有供應商爲我們的 CSS 加上前綴,有時是 polyfill 的原因,爲什麼我們花時間確保我們的 Web 應用程序的跨平臺支持,以及爲什麼有時需要相當長的時間才能利用最新和最好的 Web 功能在我們的日常工作中。

嘗試使用 Safari 訪問 StackBlitz 項目,您將看到以下屏幕,表明非基於 Chromium 的瀏覽器不支持 WebContainers。

各個瀏覽器提供商實現新功能的時效並不相同,而且不同供應商實現某些功能的方式通常也有所不同。然而,在 Interop 2022 等舉措,未來看起來一片光明。

2. 處理節點模塊導入

我們今天編寫的大多數(如果不是全部)前端應用程序都依賴於 NPM 的外部庫。對於典型的 React 應用程序,我們會在組件文件的頂部導入 React,如下所示:

嘗試直接在瀏覽器中加載它,就像我們在 Unbundled Development 中需要做的那樣,會導致兩個問題。首先,瀏覽器不知道如何解析要查找的路徑react,其次,react 庫作爲 Common JS (CJS) 模塊發佈——如果不進行一些預處理,它無法在瀏覽器中本地運行。

後者纔是更大的問題,因爲將我們的 Node 模塊導入替換爲指定文件的相對路徑是可能的,甚至是微不足道的。然而,由於大多數 NPM 包是以適用於 Node.js 而不是瀏覽器的模塊格式編寫的,這就要求我們特殊處理 NPM 依賴項,以促進 Unbundled Development。

特別是 Snowpack,它通過將應用程序的依賴項處理成單獨的 Javascript 文件,然後可以直接在瀏覽器中使用。關於 Snowpack 如何做到這一點的更多信息可以在這裏找到。

隨着 ES 模塊現在成爲大多數現代瀏覽器的主流,以及 NPM 依賴項的巧妙解決方法,像 Vite 和 Snowpack 這樣的構建工具可以提供 Unbundled 開發的選項,除了超快的 HMR 之外,還可以顯着提高性能、快速構建。

最後的思考

前端開發已經走過了漫長的道路,我們的需求也在不斷髮展和增加複雜性。構建工具是我們構建前端應用程序的重要組成部分,而現有工具還沒有達到標準,這激發了新工具的開發,這些新工具重新構想了構建工具的設計方式。

下一代構建工具非常注重性能、易用性和不太複雜的配置,有望在未來一段時間內爲雄心勃勃的前端應用程序提供支持。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/od1_nqs6bQy5PGHcvZxtZQ