Vite是什么?
Vite(法語單詞,“快” 的意思)是一種新型的前端構建工具,最初是配合 Vue3.0 一起使用的,后來適配了各種前端專案,目前提供了 Vue、React、Preact 框架模板,目前來說,Vue 使用的是 vue-cli 腳手架,React 一般使用 create-react-app 腳手架,雖然腳手架工具不一樣,但是內部的打包工具都是 Webpack,為什么要開發一個全新的構建工具,是 Webpack 不香了嗎?Vite 方式構建的專案,和使用 Webpack 構建的專案,有什么不同?一個新工具的出現,一定是為了解決現有工具存在的問題的,否則新工具就沒有存在的價值和意義,
Vite給我們帶來的就是更快的開發體驗,它實際上是一個面向現代瀏覽器,基于ECMA標準的ES module實作的一個更快更輕的Web應用開發工具,
為什么選Vite?
官網對其進行詳細的解釋:
現實問題
在瀏覽器支持 ES 模塊之前,開發者沒有以模塊化的方式開發 JavaScript 的原生機制,這也是 “打包” 這個概念出現的原因:使用工具抓取、處理和鏈接我們的原始碼模塊到檔案中,使其可以運行在瀏覽器中,
時過境遷,我們見證了許多諸如 webpack、Rollup 和 Parcel 等工具的誕生,這些工具極大地改善了前端開發者的開發體驗,
然而,當我們開始構建越來越大型的應用時,需要處理的 JavaScript 代碼量也呈指數級增長,大型專案包含數千個模塊的情況并不少見,我們開始遇到性能瓶頸 —— 使用 JavaScript 開發的工具通常需要很長時間(甚至是幾分鐘!)才能啟動開發服務器,即使使用 HMR,檔案修改后的效果也需要幾秒鐘才能在瀏覽器中反映出來,如此回圈往復,遲鈍的反饋會極大地影響開發者的開發效率和幸福感,
Vite 旨在利用生態系統中的新進展解決上述問題:瀏覽器開始原生支持 ES 模塊,越來越多 JavaScript 工具使用編譯型語言撰寫,
問題一:緩慢的服務器啟動
當冷啟動開發服務器時,基于打包器的方式是在提供服務前去急切地抓取和構建你的整個應用,
Vite 通過在一開始將應用中的模塊區分為 依賴 和 原始碼 兩類,改進了開發服務器啟動時間,
-
依賴 大多為純 JavaScript 并在開發時不會變動,一些較大的依賴(例如有上百個模塊的組件庫)處理的代價也很高,依賴也通常會以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模塊中,
Vite 將會使用 esbuild 預構建依賴,Esbuild 使用 Go 撰寫,并且比以 JavaScript 撰寫的打包器預構建依賴快 10-100 倍,
-
原始碼 通常包含一些并非直接是 JavaScript 的檔案,需要轉換(例如 JSX,CSS 或者 Vue/Svelte 組件),時常會被編輯,同時,并不是所有的原始碼都需要同時被加載,(例如基于路由拆分的代碼模塊),
Vite 以 原生 ESM 方式服務原始碼,這實際上是讓瀏覽器接管了打包程式的部分作業:Vite 只需要在瀏覽器請求原始碼時進行轉換并按需提供原始碼,根據情景動態匯入的代碼,即只在當前螢屏上實際使用時才會被處理,
兩種構建方式的對比圖


問題二:緩慢的更新
當基于打包器啟動時,編輯檔案后將重新構建檔案本身,顯然我們不應該重新構建整個包,因為這樣更新速度會隨著應用體積增長而直線下降,
一些打包器的開發服務器將構建內容存入記憶體,這樣它們只需要在檔案更改時使模塊圖的一部分失活[1],但它也仍需要整個重新構建并多載頁面,這樣代價很高,并且重新加載頁面會消除應用的當前狀態,所以打包器支持了動態模塊熱多載(HMR):允許一個模塊 “熱替換” 它自己,而對頁面其余部分沒有影響,這大大改進了開發體驗 - 然而,在實踐中我們發現,即使是 HMR 更新速度也會隨著應用規模的增長而顯著下降,
在 Vite 中,HMR 是在原生 ESM 上執行的,當編輯一個檔案時,Vite 只需要精確地使已編輯的模塊與其最近的 HMR 邊界之間的鏈失效(大多數時候只需要模塊本身),使 HMR 更新始終快速,無論應用的大小,
Vite 同時利用 HTTP 頭來加速整個頁面的重新加載(再次讓瀏覽器為我們做更多事情):原始碼模塊的請求會根據 304 Not Modified 進行協商快取,而依賴模塊請求則會通過 Cache-Control: max-age=31536000,immutable 進行強快取,因此一旦被快取它們將不需要再次請求,
注意:盡管原生 ESM 現在得到了廣泛支持,但由于嵌套匯入會導致額外的網路往返,在生產環境中發布未打包的 ESM 仍然效率低下(即使使用 HTTP/2),為了在生產環境中獲得最佳的加載性能,最好還是將代碼進行 tree-shaking、懶加載和 chunk 分割(以獲得更好的快取),
Vite的使用
1、安裝create-vite-app腳手架
npm install create-vite-app
2、搭建專案
npm init vite-app vite-project
3、 啟動專案
cd vite-project
npm install (or `yarn`)
npm run dev (or `yarn dev`)

查看專案的目錄結構

目錄結構跟平時的vue專案差不多,但是仔細觀察,index.html檔案放到了根目錄下,當vite服務啟動之后,服務器訪問的目錄就是該根目錄,比如訪問http://localhost:3000/package-lock.json
該檔案就是我們根目錄的package-lock.json

打開package.json,dependencies是vue3.0版本

專案也使用了vue3的新特性,如main.js中引入的是createApp而不是vue

組件里面的template標簽下不止一個根標簽,這也是vue3的其中一個特性

Vite的作業機制
Vite整體的作業機制,用簡單的圖表示:

根據圖片來看,Vite實際上也是一個server,在啟動vite構建web server后,即服務啟動之后(如訪問),我們訪問這個地址,該頁面會向web server發送請求,請求對應的檔案,我們可以從network中看到,如下:

注意觀察network里面的回應,我們會發現里面有兩個App.vue,兩個HelloWorld.vue,實際上這就是因為在我們請求這些檔案的時候,被vite server攔截了,經過編譯后才回傳對應的內容,
打開network里面的HelloWorld.vue

對比我們專案里面的HelloWorld.vue,兩個的內容是截然不同的

觀察network中HelloWorld.vue里面的內容
import { render as __render } from "/src/components/HelloWorld.vue?type=template"
表示引入了HelloWorld.vue?type=template,正好network里面有HelloWorld.vue?type=template請求,打開查看response,這實際就是HelloWorld.vue中template編譯之后的內容

這個作業機制也正是vite的速度快的原因,vite server攔截請求,只對請求的檔案及其依賴的模塊進行編譯,那些沒有被參考到的檔案就不會被編譯,做到了按需編譯,
證明一下,查看當前的main.js,其引入了index.css
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
createApp(App).mount('#app')
此時network中是會去請求index.css

修改main.js,去掉對index.css的引入
import { createApp } from 'vue'
import App from './App.vue'
//import './index.css'
createApp(App).mount('#app')
此時查看network中發現,index.css不去請求了

那么問題就來了,每次發請求都去攔截、編譯,豈不是每次重繪頁面都會重復之前的編譯作業(即使頁面沒做更新)?答案是不會的,剛剛我們把index.css的參考去掉了,頁面自動的重繪,觀察上圖中的狀態碼,除了幾個為200,其他的大部分為403,這代表著這些請求用的是快取里面的資源,而并沒有重新去編譯,合理利用瀏覽器的快取機制,減少請求與編譯,提升速度,
除了利用瀏覽器快取外,vite本身也有一個快取的機制,它會針對依賴的包做一個快取,這里我們可以看一下network中main.js的response,

可以發現,我們對vue的參考,變成了對@modules下的vue.js的參考,在專案的目錄,找到node_modules下的.vite_opt_cache檔案夾可以找到vue.js檔案,

與network里面的vue.js進行對比

network里面的vue.js就是vite快取里面的vue.js,是對vue進行編譯后生成的js檔案,證明一下,現在在目錄里面的vue.js檔案添加一行代碼:

重繪查看network中的vue.js,二者一致,實際上.vite_opt_cache就是用來存放被快取的依賴包的,而這里不止快取vue的依賴包,其他的依賴包也可以,比如這里我們引入一個axios ,

安裝axios依賴包
npm i axios -S
此時package.json新增一個axios的依賴

在main.js中引入axios
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import { axios } from 'axios'
createApp(App).mount('#app')
觀察network,axios已經進行編譯,重新重繪,狀態碼304

重繪根目錄,可以看到,.vite_opt_cache下多了一個axios.js

vite除了按需編譯,通過這兩種快取,又一次提升了速度,有了它,你還會使用webpack嗎?
參考鏈接:
vite學習之路(一)初識vite,vite的使用與作業機制_zem-CSDN博客_vite
Home | Vite中文網
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/347153.html
標籤:其他
