當談到前端構建工具,就不得不提的功能強大的 Webpack, 尤爲是在最新版本中提出了 Module Federation 功能,該功能進一步加強了 Webpack 的實際做用。我相信憑藉 Webpack 這幾年的積累,恐怕將來幾年內沒有哪個打包工具可以與之媲美,可是這並不妨礙咱們探討一下新的工具 Snowpack。javascript
使用 Snowpack,當您構建現代的 Web 應用程序(使用React,Vue等),無需使用相似於 Webpack,Parcel 和 Rollup 等打包工具。每次您點擊保存時,都無需等待打包程序從新構建。相反,全部的文件更改都會當即反映在瀏覽器中。css
請關注當即這個詞語, bundleless ? 這個究竟有什麼意義?爲何我會這麼重點關注這一個工具。html
對於一些項目與開發者而言,可能對此沒有太大的感觸,可是對於我來講,開發中打包曾經是一個噩夢。幾年前,我從頭開發一個前端 Sass 項目,該項目開始時候就使用 Vue 以 Webpack 根據業務線構建多頁面。幾個月的時間過去,模塊有了十幾個。當我修改一個很小的地方時候,須要近一分鐘的時候才能熱更新完成。當時,咱們只能在項目開啓的時候設置那些頁面須要編譯。在忍受了一週後,咱們不得不開始拆分項目,由於開發人員和項目開發效率的緣由,咱們不可能根據業務拆分項目。咱們只能把項目中改動較少的的基礎服務以及封裝的業務組件給提取出去。利用 Webpack 的 externals 來輔助開發。這個方案很好的解決了項目當時的痛點。同時,這件事也讓我對於模塊劃分和性能優化有了必定的認識和看法。前端
因此,在我看來,bundleless 解決了大部分前端開發者 的一大痛點,就是心流)。當一個程序員被打攪後,他須要 10 - 15 分鐘的時間才能從新恢復到以前的編程狀態。當你在完成一小塊功能時候,想要去查看結果時候,發現當前的項目還在構建狀態,這個時候頗有可能就會停止心流。vue
固然,還有一些高明的程序員是完成整塊功能再去查看結果。同時開發的 bug 也很是少。該工具對於此類程序員的幫助也不大。談到這裏,我很想要多說兩句,雖然程序員在開發中須要學習和使用大量的工具輔助開發,事實上不少工具也確實可以提高效率,可是有時候須要逼本身一把,把本身置身於資源不那麼足夠的狀況下,由於只有這樣才能真正的提高能力。這裏我推薦一篇博客 斷點單步跟蹤是一種低效的調試方法,無論你們是承認仍是否定,我認爲均可以從這篇博客中獲得思考。java
就目前成熟的前端框架來講,都會提供一套腳手架工具以便用戶使用。以前咱們也是把項目直接從 Webpack 轉到了 Vue Cli 3。由於 Vue Cli 3 內部封裝了 Webpack, 基本上在開發中已經不須要進行 Webpack 基礎性配置,同時咱們所須要的依賴項目也大大減小了,底層的依賴升級也轉移到了 Vue Cli 上,這也變相的減小了不少的開發量。node
在探討 Snowpack 這個新的構建工具以前,我要拋出一個問題,咱們究竟爲何要使用 Webpack? webpack
一個固然是由於 Webpack 確實提供了不少高效有用的工程實踐爲前端開發者賦能。若是讓咱們自行研究與使用,須要投入的時間以及掌握的知識遠遠高於配置學習成本。第二個就是由於它自己是一個靜態的 JavaScript 應用程序的靜態模塊打包工具,首要的重點就在於工具爲前端提供了模塊與打包。git
當年的 JavaScript 設計之初爲了保持簡單,缺乏其餘通用語言都具備的模塊特性。而該特性正是組織大型,複雜的項目所必須的。但當年的 JavaScript 的工做就是實現簡單的提交表單,寥寥幾行代碼便可實現功能。即便 Ajax 標誌 Web 2.0 時代的到來階段,前端開發的重點仍是放在減小全局變量上,因而咱們開始使用 IIFE(當即調用函數表達式)來減小全局變量的污染, 而 IIFE 方法存在的問題是沒有明確的依賴關係樹。開發人員必須以準確的順序來組織文件列表,以保證模塊之間的依賴關係。因爲當時網頁短暫的生命週期以及後端渲染機制保證了網頁的依賴是可控的。程序員
在以後,Node.js 出世,讓 JavaScript 能夠開發後端,在 Node.js 的許多創新中,值得一提的是 CommonJS 模塊系統,或者簡稱爲CJS。 利用 Node.js 程序能夠訪問文件系統的事實,CommonJS 標準更具備傳統的模塊加載機制。 在 CommonJS 中,每一個文件都是一個模塊,具備本身的做用域和上下文。固然,雖然這種機制也底層來自也來自於 IIFE(當即調用函數表達式)。這種創新的爆發不只來自創造力,還來自於自於必要性:當應用程序變得愈來愈複雜。 控制代碼間的依賴關係越來遇難,可維護性也愈來愈差。咱們須要模塊系統以適應那些擴展以及變動的需求,而後圍繞它們的生態系統將開發出更好的工具,更好的庫,更好的編碼實踐,體系結構,標準以及模式。終於,伴隨模塊系統的實現,JavaScript 終於具備了開發大型複雜項目的可能性。
雖然在此以後開發了各式各樣的模塊加載機制,諸如 AMD UMD 等,可是等到 ES6 的到來。JavaScript 才正式擁有了本身的模塊,一般稱爲ECMAScript模塊(ESM)。也是 SnowPack 依賴的基礎,這一點咱們後面展開來講。
相比於CommonJS , ES 模塊是官方標準,也是 JavaScript 語言明確的發展方向,而 CommonJS 模塊是一種特殊的傳統格式,在 ESM 被提出以前作爲暫時的解決方案。 ESM 容許進行靜態分析,從而實現像 tree-shaking 的優化,並提供諸如循環引用和動態綁定等高級功能。同時在 Node v8.5.0 以後也能夠在實現標準的狀況下使用 ESM,隨着Node 13.9.0 版本的發佈,ESM 已經能夠在沒有實驗性標誌的狀況下使用。
Webpack 一方面解決了前端構建大型項目的問題,另外一方面提供了插件優化 Web 前端性能。例如從資源合併以及壓縮上解決了 HTTP 請求過程的問題,把小圖片打包爲 base64 以減小請求量,提供 Tree-Shaking 以及動態導入。伴隨着 HTTP 協議的升級以及網速的不斷加快,我也但願往後這些工做慢慢變成負擔。
SnowPack 是基於 ESM 的工具。想要經過一次安裝來替換每次更改時候重建的構建步驟。ESM 如今能夠在瀏覽器中使用了! 咱們可使用 [Can i use]()瞭解一下 ESM 的可使用性。
能夠看到,基本上現代瀏覽器都已經提供了支持,事實上咱們也不須要等到全部的瀏覽器提供支持。
咱們不須要爲全部瀏覽器提供一致性的體驗,咱們也作不到這一點。事實上,咱們在這件事情上是能夠作到漸進加強的。對於不支持的瀏覽器,徹底沒法理解該語句,也不會去 js 加載。例如能夠提供頁面預加載的前端庫 instant.page。該庫在不支持 ESM 的瀏覽器上壓根不會執行。
同時對於暫時不支持的瀏覽器來講,依然能夠加載 js ,惟一須要作的就是爲不支持 <script type="module"> 的瀏覽器提供一個降級方案。。正以下面的代碼,在現代瀏覽器中,會加載 module.mjs,同時現代瀏覽器會忽略攜帶 nomodule 的js。而在以前的瀏覽器會加載後面的 js 文件。若是你想進一步閱讀的話,能夠參考 ECMAScript modules in browsers 。
<script type="module" src="module.mjs"></script> <script nomodule src="fallback.js"></script>
同時,咱們能夠經過 type="module" 來判斷出現代的瀏覽器。而支持type="module" 的瀏覽器都支持你所熟知的大部分 ES6 語法,經過這個特性,咱們能夠打包出兩種代碼,爲現代瀏覽器提供新的代碼,而爲不支持 ESM 的瀏覽器提供另外一套代碼, 具體能夠參考 Phillip Walton 精彩的博文,這裏也有翻譯版本 如何在生產環境中部署ES2015+。若是當前項目已經開始從 webpack 陣營轉到 Vue CLI 陣營的話,那麼恭喜你,上述解決方案已經被內置到 Vue CLI 當中去了。只須要使用以下指令,項目便會產生兩個版本的包。具體能夠參考 Vue CLI 現代模式。
出於對主流瀏覽器的判斷,SnowPack 大膽採用 ESM,其原理也很簡單,內部幫助咱們將 node_modules 的代碼整理而且安裝到 一個叫作 web_modules 的文件夾中,須要的時候直接到該文件夾中引入便可。其目標也是爲了解決第三方代碼的引入問題。(註明: 安裝 Snowpack 須要 node v10.17.0 以上版本)
固然,若是僅僅只爲了解決第三方引入的問題,事實上咱們本身也能夠手動解決,可是面對錯綜複雜的第三方庫,咱們本身經過 node 來構建未免有些過於複雜。同時,該工具依然會提供使用 TypeScript 以及 Babel 的方案 ,同時也爲咱們提供了少許的配置選項來幫助咱們管理第三方依賴。同時,Snowpack 還能夠經過 --nomodule 支持舊版瀏覽器。同時它也能夠根據當前引入的模塊來自動構建依賴。
當瀏覽器自己已經開始支持模塊,若是網絡速度已經再也不是限制,那麼咱們是否應該離開復雜的構建環境轉向簡單的代碼? 答案是確定的,簡單的方案必定會贏得開發者的青睞。
說到這裏,我不由想到當年剛剛學習軟件時侯老是遇到 BS (瀏覽器與服務器)架構和 CS (客戶端與服務器) 架構的問題與選擇。歷史的選擇告訴咱們,可以使用 BS 架構的軟件,必定會用 BS 架構。若是桌面端的 CS 轉向 BS 是一條漫長的探索之路,那麼移動端的 CS 轉向 BS 則是必經之路。
對於 Vue 這種漸進式的框架來講,即便沒有打包工具,咱們依然能夠在 html 中直接引入開發,而對於 React, Svelte 這些須要編譯纔可以使用的庫來講,SnowPack 也提供了方案來幫助咱們協做解決。對於 css 圖片這些,瀏覽器不支持用 js 導入,咱們還須要爲其改造,具體的實現能夠直接學習 Snowpack 官網 以及 Snowpack 例子。
說了 Snowpack 的優點,咱們也必須聊一聊 Snowpack 的劣勢。過於激進必定是劣勢,畢竟不支持 ESM 的庫仍是不少,面對企業應用開發,咱們仍是須要穩定的工具。同時面對強大腳手架工具,過於捉襟見肘,須要付出更大的精力來維持系統的一致性。同時,在瀏覽器使用模塊化以後,前端代碼更容易被分析,這個是否會影響項目自己,事實上也有待商榷。沒有模塊熱更新功能,這點令開發很痛苦。
前兩天,Vue3 beta 版本出世,在直播中,Vue 開發者尤雨溪也是順帶說了一下爲 Vue 3 提供的「小」工具 vite ,我在閒暇之時也是去把玩了一下。該工具也是根據瀏覽器 ESM 結合 node 來針對每一個更改模塊進行即時編譯後直接提供給瀏覽器。 也就是說,當你在開發中修改了某個 vue 文件以後,node 會編譯該文件而且經過 HMR 提供給瀏覽器當前編譯後的 vue 文件。
相對比 Snowpack 來講,該方案則更加優美 (我的感受)。同時兼顧了開發和生產環境。雖然在當前階段還不能投入生產,可是我相信 vite 在將來會大放光芒。
前幾年,咱們須要 Webpack 配置工程師,隨着 Parcel 的發佈, Webpack 隨後也提供了零配置,伴隨着依賴升級的複雜度一步步變高,各個框架也是將 Webpack 做爲本身的依賴提供更優的工具,伴隨着 bundleless。咱們能夠看到,前端開發難度下降的同時體驗也在提高,這是一件好事。
同時,雲端 Serverless 架構也下降了創業公司對基礎建設的需求。也許未來真的會有業務人員投入到開發中來。而咱們也有更多的時間投入到業務場景與業務需求中去。
若是你以爲這篇文章不錯,但願能夠給與我一些鼓勵,在個人 github 博客下幫忙 star 一下。