Snowpack,新時(shí)代前端構(gòu)建的先鋒
大家好,我是三元同學(xué)。
今天給大家介紹一個(gè)非常厲害的前端構(gòu)建工具——Snowpack。也許你之前聽說過前端領(lǐng)域非常多的打包工具,諸如 Webpack、Rollup,或者Parcel,甚至是現(xiàn)在在前端圈大火的 Bundleless 構(gòu)建工具Vite,但大家也許并沒有注意到 Snowpack。
其實(shí)它在 2019 年 2 月就在開源社區(qū)誕生了,可以說是業(yè)界最早提出并實(shí)現(xiàn)的 Bundleless 方案,如今在社區(qū)已經(jīng)有了不小的影響力,Github 上的 star 已經(jīng)超過了兩萬,而尤大本人也承認(rèn)早期 Vite 的設(shè)計(jì)也確實(shí)受到了 Snowpack 的啟發(fā)。不管怎么說,Snowpack 本身是一個(gè)非常優(yōu)秀的方案,背后的開發(fā)團(tuán)隊(duì)是一支非常值得 respect 的團(tuán)隊(duì),我想很有必要將這個(gè)方案分享給大家。
時(shí)代先鋒隊(duì)——Pika
Snowpack 的開發(fā)團(tuán)隊(duì)名為Pika,團(tuán)隊(duì)的技術(shù)緊跟時(shí)代的最前沿,在開發(fā) Snowpack 這個(gè)新時(shí)代前端構(gòu)建工具的同時(shí),也率先提出了Skypack這種造福大眾的針對 ESM 格式第三方庫的 CDN 服務(wù)(后續(xù)再跟大家詳細(xì)介紹這個(gè)服務(wù)到底有多吸引人)。
他們有一個(gè)使命: 讓 Web 項(xiàng)目構(gòu)建速度加快 90%。
作為走在時(shí)代前沿的他們,始終貫穿著一句研發(fā)宗旨:
- You should be able to use a bundler because you want to, and not because you need to.
換句話說,在現(xiàn)在的 Web 開發(fā)時(shí)代,打包不再是必需的選項(xiàng),而只是一種優(yōu)化的手段,不用打包也能運(yùn)行你的應(yīng)用。現(xiàn)代 Web 構(gòu)建要變天了,未來即將進(jìn)入一個(gè) Bundleless(顧名思義,更少的打包,更快的構(gòu)建速度)的時(shí)代,Web 領(lǐng)域在經(jīng)歷之前一系列的工程化改革之后,現(xiàn)在即將又要迎來一場翻天覆地的革新浪潮,而 Snowpack 之父——Pika 團(tuán)隊(duì)就是跨時(shí)代的弄潮兒,Snowpack 就是 Pika 團(tuán)隊(duì)創(chuàng)造新時(shí)代而打響的第一槍!
Why?
Snowpack 為什么會誕生?Web 構(gòu)建為什么會進(jìn)入 Bundleless 的時(shí)代?為什么 Pika 團(tuán)隊(duì)寧愿傾其所有去改變當(dāng)下 Web 項(xiàng)目的構(gòu)建現(xiàn)狀?在真正介紹 Snowpack 之前,這些問題,必須得弄清楚。
在很久很久以前,開發(fā)前端網(wǎng)頁,似乎并沒有現(xiàn)在這么繁雜的工具鏈和框架,僅僅寫一些原生的 HTML 代碼、CSS 和一些 JavaScript 代碼,那個(gè)時(shí)候怎么啟動(dòng)項(xiàng)目?直接打開 HTML 文件!我改動(dòng)了代碼怎么看到更新?直接刷新網(wǎng)頁!一切看上去都是那么的絲滑,所見即所得,可以說那個(gè)時(shí)候的前端,足夠開門見山,足夠簡單粗暴,簡單得甚至讓人有些懷念。
直到后來,隨著前端的邏輯越來越復(fù)雜,對模塊化的需求越來越強(qiáng)烈,逐漸出現(xiàn)了 CommonJS(2009 年)、AMD(2010 年)、UMD(2011 年)這些模塊規(guī)范,底層的規(guī)范出現(xiàn)并穩(wěn)定之后必然會有上層的工具來實(shí)現(xiàn),由此出現(xiàn)了一系列的工程化方案:
- 模塊加載器,比如 SeaJS
- 包管理器,比如 npm
- 打包器,比如 Browserify、Gulp、Webpack
更重要的是,09 的時(shí)候 Ryan Dahl 寫出了一個(gè)叫 Node.js 的東西,給 JS 帶來了全新的可能,以前 Java、C++ 能寫的工具,用 JS 照樣能寫了! 也就是從這個(gè)時(shí)候開始,前端開始變復(fù)雜了,各種工具鏈開始亂花漸欲迷人眼,尤其是在 2015 年 ESModule 標(biāo)準(zhǔn)的誕生,再次將工程化方案之爭推上風(fēng)口浪尖,最后的勝出者很明顯了,就是在座各位如今幾乎天天能遇到的Webpack、Babel,這兩個(gè)東西,甚至已經(jīng)成為了如今前端工程化的代名詞了。
Babel 不用多說,是鼎鼎有名的 JavaScript 編譯器,在讓人眼花繚亂的語法標(biāo)準(zhǔn)中,它能夠?qū)㈧`活地一份 JS 代碼從一種語法標(biāo)準(zhǔn)轉(zhuǎn)換到另一種語法標(biāo)準(zhǔn)。
Webpack 是干什么的呢?它給自己的定位其實(shí)很簡單,就是一個(gè)模塊打包器。
它的理念是:萬物皆模塊。
不管代碼里面依賴關(guān)系多復(fù)雜,按照它的模塊導(dǎo)入導(dǎo)出語法來寫,寫完之后把入口扔給它,它給你理清所有的依賴關(guān)系,最后打包到一起,給你一份產(chǎn)物,甭管這份產(chǎn)物你能不能看得懂,你大可以放心,瀏覽器看得懂,并且代碼性能和安全性也都還不錯(cuò)。
當(dāng)然,作為打包器,Rollup包括Parcel現(xiàn)在也都是很亮眼的存在,不過在 Webpack 強(qiáng)大的生態(tài)和業(yè)界落地基礎(chǔ)面前,二位就相形見絀了。
但總體來說,對于這樣的打包器而言,一定是有潛在的性能風(fēng)險(xiǎn)的,因?yàn)樗臉?gòu)建時(shí)間是和項(xiàng)目的整體規(guī)模成正比的,也就是說,項(xiàng)目規(guī)模的變大難以避免構(gòu)建時(shí)長不斷增加,現(xiàn)在的前端項(xiàng)目可以說要多復(fù)雜有多復(fù)雜,你可以盡情地想象打包器的這種性質(zhì)帶來的后果。
果然,這一天還是來了。
五年前,我用 Webpack 打包,啟動(dòng)還挺快的。
五年后,我還是在用 Webpack 打包,團(tuán)隊(duì)多了 20 個(gè)人,代碼多了 20 萬行,現(xiàn)在啟動(dòng)一次要 10 分鐘!代碼改動(dòng)一次,看到結(jié)果更新要等 30000 ms!😭
直到 2018 年的某一天,主流的瀏覽器 Chrome/Safafi/Firefox 開始支持 ESModule,跟開發(fā)者們說,你們只需要把入口代碼扔進(jìn)來,我給你請求所有需要導(dǎo)入的模塊,你們不用再煞費(fèi)苦心寫什么打包器把代碼放到一起了。
在這時(shí),Pika 團(tuán)隊(duì)登場,向全世界宣告: 未來的曙光已經(jīng)出現(xiàn),想要擺脫當(dāng)下的困境,請跟著我們一起朝著光的方向奔跑!
這道曙光指的就是瀏覽器開始支持 ESModule 標(biāo)準(zhǔn),他們務(wù)必堅(jiān)定地相信這件事情,并且由于 HTTP/2 的普及,以前將多個(gè)靜態(tài)資源打包到一起從而減少請求次數(shù)的性能優(yōu)化手段不再成為必須,所以打包這個(gè)過程也就不再必要。
本著這樣的信念和基礎(chǔ),一年之后他們宣布了 Snowpack 的誕生,新時(shí)代的第一份 Bundleless 方案終于問世。
和 Webpack 的關(guān)系
一方面,與 Webpack 對比,Snowpack 的優(yōu)勢就在于它的構(gòu)建速度特別快。這種快主要體現(xiàn)在兩個(gè)方面:
開發(fā)階段相當(dāng)于啟動(dòng)一個(gè) Dev Server,無需將業(yè)務(wù)代碼進(jìn)行打包,也就省略了一系列分析依賴、代碼打包的繁瑣過程,甚至可以直接秒起。
無論項(xiàng)目規(guī)模如何增加,構(gòu)建時(shí)間復(fù)雜度始終為O(1),不會隨項(xiàng)目規(guī)模不斷增長。
可以看到,當(dāng)文件變更之后,對于 Webpack 來說,為了整體打包,它需要重新構(gòu)建依賴圖,但對于代表 Bundleless 的 Snowpack 則不是這樣,每次都是單文件編譯,構(gòu)建速度不再受限于項(xiàng)目規(guī)模,也帶來了文件改動(dòng)后極快的更新速度。
而另一方面,Snowpack 并不排斥 Webpack,在生產(chǎn)環(huán)境構(gòu)建階段,Snowpack 本身也是提供了插件機(jī)制來集成其它的打包器,并且官方提供了開箱即用的插件 @snowpack/plugin-webpack 直接集成 Webpack。這也是相對于 Vite 更加靈活的地方,Vite 只能選擇 Rollup 進(jìn)行生產(chǎn)環(huán)境打包,但 Snowpack 可以直接不打包,也可以選擇集成任何一個(gè)打包器(Webpack、Rollup或Esbuild)進(jìn)行打包。
小結(jié)
這次我們仔細(xì)分析了 Snowpack 誕生的歷史背景和實(shí)現(xiàn)基礎(chǔ),相信你也對 Bundleless 有了初步的認(rèn)識。當(dāng)然知道這些還遠(yuǎn)遠(yuǎn)不夠,關(guān)于 Snowpack 以及 Bundleless,有很多的細(xì)節(jié)需要展開,包括依賴預(yù)構(gòu)建、Streaming Imports、插件架構(gòu)、HMR 系統(tǒng)、服務(wù)端渲染支持等等,后續(xù)我們會逐漸從使用到內(nèi)部實(shí)現(xiàn),逐步深入 Snowpack 的方方面面,讓你一覽新時(shí)代構(gòu)建工具的風(fēng)采。