Vite和Webpack的核心差異
?? 點(diǎn)擊上方“前端簡(jiǎn)報(bào)”,進(jìn)行關(guān)注


第一時(shí)間關(guān)注技術(shù)干貨!
寫(xiě)在開(kāi)頭
最近的 vite比較火,而且發(fā)布了2.0版本,vue的作者也是在極力推薦在之前的文章里面我提到過(guò), vite的缺點(diǎn)在于目前的生態(tài)不夠webpack成熟,但是只要能彌補(bǔ)這個(gè)缺點(diǎn),便有很大概率能替代目前webpack的大部分市場(chǎng)
全方位對(duì)比vite和webpack
webpack打包過(guò)程
1.識(shí)別入口文件
2.通過(guò)逐層識(shí)別模塊依賴(lài)。(Commonjs、amd或者es6的import,webpack都會(huì)對(duì)其進(jìn)行分析。來(lái)獲取代碼的依賴(lài))
3.webpack做的就是分析代碼。轉(zhuǎn)換代碼,編譯代碼,輸出代碼
4.最終形成打包后的代碼
webpack打包原理
1.
先逐級(jí)遞歸識(shí)別依賴(lài),構(gòu)建依賴(lài)圖譜2.將代碼轉(zhuǎn)化成AST抽象語(yǔ)法樹(shù)
3.在AST階段中去處理代碼
4.把AST抽象語(yǔ)法樹(shù)變成瀏覽器可以識(shí)別的代碼, 然后輸出
重點(diǎn):這里需要遞歸識(shí)別依賴(lài),構(gòu)建依賴(lài)圖譜。圖譜對(duì)象就是類(lèi)似下面這種
{ './app.js':
{ dependencies: { './test1.js': './test1.js' },
code:
'"use strict";\n\nvar _test = _interopRequireDefault(require("./test1.js"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n\nconsole.log(test
1);' },
'./test1.js':
{ dependencies: { './test2.js': './test2.js' },
code:
'"use strict";\n\nvar _test = _interopRequireDefault(require("./test2.js"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n\nconsole.log(\'th
is is test1.js \', _test["default"]);' },
'./test2.js':
{ dependencies: {},
code:
'"use strict";\n\nObject.defineProperty(exports, "__esModule", {\n value: true\n});\nexports["default"] = void 0;\n\nfunction test2() {\n console.log(\'this is test2 \');\n}\n\nvar _default = tes
t2;\nexports["default"] = _default;' } }

vite原理
當(dāng)聲明一個(gè) script 標(biāo)簽類(lèi)型為 module 時(shí)
如:
<script type="module" src="/src/main.js"></script>
瀏覽器就會(huì)像服務(wù)器發(fā)起一個(gè)GET
http://localhost:3000/src/main.js請(qǐng)求main.js文件:
// /src/main.js:
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
瀏覽器請(qǐng)求到了main.js文件,檢測(cè)到內(nèi)部含有import引入的包,又會(huì)對(duì)其內(nèi)部的 import 引用發(fā)起 HTTP 請(qǐng)求獲取模塊的內(nèi)容文件
如:
GET http://localhost:3000/@modules/vue.js如:
GET http://localhost:3000/src/App.vueVite的主要功能就是通過(guò)劫持瀏覽器的這些請(qǐng)求,并在后端進(jìn)行相應(yīng)的處理將項(xiàng)目中使用的文件通過(guò)簡(jiǎn)單的分解與整合,然后再返回給瀏覽器,vite整個(gè)過(guò)程中沒(méi)有對(duì)文件進(jìn)行打包編譯,所以其運(yùn)行速度比原始的webpack開(kāi)發(fā)編譯速度快出許多!
webpack缺點(diǎn)一。緩慢的服務(wù)器啟動(dòng)
當(dāng)冷啟動(dòng)開(kāi)發(fā)服務(wù)器時(shí),基于打包器的方式是在提供服務(wù)前去急切地抓取和構(gòu)建你的整個(gè)應(yīng)用。
vite改進(jìn)
Vite 通過(guò)在一開(kāi)始將應(yīng)用中的模塊區(qū)分為 依賴(lài) 和 源碼 兩類(lèi),改進(jìn)了開(kāi)發(fā)服務(wù)器啟動(dòng)時(shí)間。
依賴(lài) 大多為純 JavaScript 并在開(kāi)發(fā)時(shí)不會(huì)變動(dòng)。一些較大的依賴(lài)(例如有上百個(gè)模塊的組件庫(kù))處理的代價(jià)也很高。依賴(lài)也通常會(huì)以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模塊中。
Vite 將會(huì)使用 esbuild 預(yù)構(gòu)建依賴(lài)。Esbuild 使用 Go 編寫(xiě),并且比以 JavaScript 編寫(xiě)的打包器預(yù)構(gòu)建依賴(lài)快 10-100 倍。
源碼 通常包含一些并非直接是 JavaScript 的文件,需要轉(zhuǎn)換(例如 JSX,CSS 或者 Vue/Svelte 組件),時(shí)常會(huì)被編輯。同時(shí),并不是所有的源碼都需要同時(shí)被加載。(例如基于路由拆分的代碼模塊)。
Vite 以 原生 ESM 方式服務(wù)源碼。這實(shí)際上是讓瀏覽器接管了打包程序的部分工作:Vite 只需要在瀏覽器請(qǐng)求源碼時(shí)進(jìn)行轉(zhuǎn)換并按需提供源碼。根據(jù)情景動(dòng)態(tài)導(dǎo)入的代碼,即只在當(dāng)前屏幕上實(shí)際使用時(shí)才會(huì)被處理。
webpack缺點(diǎn)2.使用的是node.js去實(shí)現(xiàn)

vite改進(jìn)
Vite 將會(huì)使用 esbuild預(yù)構(gòu)建依賴(lài)。Esbuild 使用 Go 編寫(xiě),并且比以Node.js編寫(xiě)的打包器預(yù)構(gòu)建依賴(lài)快 10-100 倍。
webpack致命缺點(diǎn)3.熱更新效率低下
當(dāng)基于打包器啟動(dòng)時(shí),編輯文件后將重新構(gòu)建文件本身。顯然我們不應(yīng)該重新構(gòu)建整個(gè)包,因?yàn)檫@樣更新速度會(huì)隨著應(yīng)用體積增長(zhǎng)而直線(xiàn)下降。
一些打包器的開(kāi)發(fā)服務(wù)器將構(gòu)建內(nèi)容存入內(nèi)存,這樣它們只需要在文件更改時(shí)使模塊圖的一部分失活[1],但它也仍需要整個(gè)重新構(gòu)建并重載頁(yè)面。這樣代價(jià)很高,并且重新加載頁(yè)面會(huì)消除應(yīng)用的當(dāng)前狀態(tài),所以打包器支持了動(dòng)態(tài)模塊熱重載(HMR):允許一個(gè)模塊 “熱替換” 它自己,而對(duì)頁(yè)面其余部分沒(méi)有影響。這大大改進(jìn)了開(kāi)發(fā)體驗(yàn) - 然而,在實(shí)踐中我們發(fā)現(xiàn),即使是 HMR 更新速度也會(huì)隨著應(yīng)用規(guī)模的增長(zhǎng)而顯著下降。
vite改進(jìn)
在 Vite 中,HMR 是在原生 ESM 上執(zhí)行的。當(dāng)編輯一個(gè)文件時(shí),
Vite 只需要精確地使已編輯的模塊與其最近的 HMR 邊界之間的鏈?zhǔn)Вù蠖鄶?shù)時(shí)候只需要模塊本身),使 HMR 更新始終快速,無(wú)論應(yīng)用的大小。Vite 同時(shí)利用 HTTP 頭來(lái)加速整個(gè)頁(yè)面的重新加載(再次讓瀏覽器為我們做更多事情):源碼模塊的請(qǐng)求會(huì)根據(jù) 304 Not Modified 進(jìn)行協(xié)商緩存,而依賴(lài)模塊請(qǐng)求則會(huì)通過(guò) Cache-Control: max-age=31536000,immutable 進(jìn)行強(qiáng)緩存,因此一旦被緩存它們將不需要再次請(qǐng)求。
vite缺點(diǎn)1.生態(tài),生態(tài),生態(tài)不如webpack
wepback牛逼之處在于loader和plugin非常豐富,不過(guò)我認(rèn)為生態(tài)只是時(shí)間問(wèn)題,現(xiàn)在的vite,更像是當(dāng)時(shí)剛出來(lái)的M1芯片Mac,我當(dāng)時(shí)非常看好M1的Mac,毫不猶豫買(mǎi)了,現(xiàn)在也沒(méi)什么問(wèn)題
vite缺點(diǎn)2.prod環(huán)境的構(gòu)建,目前用的Rollup
原因在于esbuild對(duì)于css和代碼分割不是很友好
vite缺點(diǎn)3.還沒(méi)有被大規(guī)模使用,很多問(wèn)題或者訴求沒(méi)有真正暴露出來(lái)
vite真正崛起那一天,是跟vue3有關(guān)系的,當(dāng)vue3廣泛開(kāi)始使用在生產(chǎn)環(huán)境的時(shí)候,vite也就大概率意味著被大家慢慢開(kāi)始接受了
總結(jié)
Vite,就像剛出來(lái)的
M1芯片Mac,都說(shuō)好,但是一開(kāi)始買(mǎi)的人不多,擔(dān)心生態(tài)問(wèn)題,后面都說(shuō)真香相信vue3作者的大力支持下,
vite即將大放異彩!我已經(jīng)在我自己項(xiàng)目的生產(chǎn)環(huán)境中,開(kāi)始使用vite!
