2021-03-18【技術(shù)】關(guān)于前端新玩具:Vite 及相關(guān)思考

Vite 的定義
Vite 是面向現(xiàn)代瀏覽器的一個(gè)更輕、更快的 Web 應(yīng)用開(kāi)發(fā)工具,核心基于 ECMAScript 標(biāo)準(zhǔn)原生模塊系統(tǒng)(ES Modules)實(shí)現(xiàn)细疚。

從表象功能上看躁垛,Vite 可以取代基于 Webpack 的 vue-cli 或者 cra 的集成式開(kāi)發(fā)工具,提供全新的一種開(kāi)發(fā)體驗(yàn)洲鸠。

Vite 的由來(lái)
在此之前堂淡,如果我們所開(kāi)發(fā)的應(yīng)用比較復(fù)雜(代碼量偏大),使用 Webpack 的開(kāi)發(fā)過(guò)程相對(duì)沒(méi)有那么「絲滑」扒腕,具體表現(xiàn)為以下兩點(diǎn):

Webpack Dev Server 冷啟動(dòng)時(shí)間會(huì)比較長(zhǎng)绢淀,稍大一點(diǎn)的項(xiàng)目啟動(dòng)開(kāi)發(fā)服務(wù)都需要等待 10 - 20 秒;
Webpack HMR 熱更新的反應(yīng)速度比較慢瘾腰,修改完代碼需要等待編譯器全部編譯完成才能開(kāi)始同步到瀏覽器皆的;
快速上手
這里我們?cè)挷欢嗾f(shuō),先上手體驗(yàn)一下 Vite蹋盆,然后再來(lái)分析其內(nèi)部的思路和想法费薄。

Vite 官方目前提供了一個(gè)比較簡(jiǎn)單的腳手架:create-vite-app,可以使用這個(gè)腳手架快速創(chuàng)建一個(gè)使用 Vite 構(gòu)建的 Vue.js 應(yīng)用

$ npm init vite-app <project-name>
$ cd <project-name>
$ npm install
$ npm run dev

如果使用 yarn:

$ yarn create vite-app <project-name>
$ cd <project-name>
$ yarn
$ yarn dev

P.S.
npm init 或者 yarn create 是這兩個(gè)包管理工具提供的新功能栖雾,其內(nèi)部就是自動(dòng)去安裝一個(gè) create-<xxx> 的模塊(臨時(shí))楞抡,然后自動(dòng)執(zhí)行這個(gè)模塊中的 bin。例如:yarn create react-app my-react-app 就相當(dāng)于先 yarn global add create-react-app岩灭,然后自動(dòng)執(zhí)行 create-react-app my-react-app拌倍。

對(duì)比差異點(diǎn)

打開(kāi)生成的項(xiàng)目過(guò)后,你會(huì)發(fā)現(xiàn)就是一個(gè)很普通的 Vue.js 應(yīng)用,沒(méi)有太多特殊的地方柱恤。
不過(guò)相比于之前 vue-cli 創(chuàng)建的項(xiàng)目或者是基于 Webpack 搭建的 Vue.js 項(xiàng)目数初,這里的開(kāi)發(fā)依賴非常簡(jiǎn)單,只有 vite 和 @vue/compiler-sfc梗顺。

{
  "name": "vite-demo",
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  },
  "dependencies": {
    "vue": "^3.0.0-rc.1"
  },
  "devDependencies": {
    "vite": "^1.0.0-rc.1",
    "@vue/compiler-sfc": "^3.0.0-rc.1"
  }
} 

Vite 就是我們今天要介紹的主角泡孩,而 @vue/compiler-sfc 就是用來(lái)編譯我們項(xiàng)目中 .vue 結(jié)尾的單文件組件(SFC),它取代的就是 Vue.js 2.x 時(shí)使用的 vue-template-compiler寺谤。

再者就是 Vue.js 的版本是 3.0仑鸥。這里尤其需要注意:Vite 目前只支持 Vue.js 3.0 版本。

在vue中变屁,因?yàn)?Webpack Dev Server 在啟動(dòng)時(shí)眼俊,需要先 build 一遍,而 build 的過(guò)程是需要耗費(fèi)很多時(shí)間的粟关。


vue-cli-service serve

而 Vite 則完全不同疮胖,當(dāng)我們執(zhí)行 vite serve 時(shí),內(nèi)部直接啟動(dòng)了 Web Server闷板,并不會(huì)先編譯所有的代碼文件澎灸。
那僅僅是啟動(dòng) Web Server,速度上自然就快了很多遮晚。


vite serve

原理:
像 Webpack 這類(lèi)工具的做法是將所有模塊提前編譯性昭、打包進(jìn) bundle 里,換句話說(shuō),不管模塊是否會(huì)被執(zhí)行,都要被編譯和打包到 bundle 里。隨著項(xiàng)目越來(lái)越大打包后的 bundle 也越來(lái)越大,打包的速度自然也就越來(lái)越慢姻乓。

Vite 利用現(xiàn)代瀏覽器原生支持 ESM 特性,省略了對(duì)模塊的打包跷叉。對(duì)于需要編譯的文件嫌吠,Vite 采用的是另外一種模式:即時(shí)編譯。也就是說(shuō)搁拙,只有具體去請(qǐng)求某個(gè)文件時(shí)才會(huì)編譯這個(gè)文件秒梳。所以,這種「即時(shí)編譯」的好處主要體現(xiàn)在:按需編譯箕速。

除此之外

Vite 還提供了一個(gè)目前在幫助列表中并沒(méi)有呈現(xiàn)的一個(gè)子命令:optimize酪碘。

這個(gè)命令的作用就是單獨(dú)的去「優(yōu)化依賴」。

所謂的「優(yōu)化依賴」盐茎,指的就是自動(dòng)去把代碼中依賴的第三方模塊提前編譯出來(lái)兴垦。

例如,我們?cè)诖a中通過(guò) import 載入了 vue 這個(gè)模塊,那通過(guò)這個(gè)命令就會(huì)自動(dòng)將這個(gè)模塊打包成一個(gè)單獨(dú)的 ESM bundle, 放到 node_modules/.vite_opt_cache 目錄中探越。

這樣后續(xù)請(qǐng)求這個(gè)文件時(shí)就不需要再即時(shí)去加載了狡赐。

HMR

同樣也是模式的問(wèn)題,熱更新的時(shí)候钦幔,Vite 只需要立即編譯當(dāng)前所修改的文件即可枕屉,所以響應(yīng)速度非常快鲤氢。

而 Webpack 修改某個(gè)文件過(guò)后搀擂,會(huì)自動(dòng)以這個(gè)文件為入口重寫(xiě) build 一次,所有的涉及到的依賴也都會(huì)被加載一遍卷玉,所以反應(yīng)速度會(huì)慢很多哨颂。

Build

Vite 在生產(chǎn)模式下打包,需要使用 vite build 命令相种。

這個(gè)命令內(nèi)部采用的是 Rollup 完成的應(yīng)用打包咆蒿,最終還是會(huì)把文件都提前編譯并打包到一起。

對(duì)于 Code Splitting 需求蚂子,Vite 內(nèi)部采用的就是原生 Dynamic imports 特性實(shí)現(xiàn)的沃测,所以打包結(jié)果還是只能夠支持現(xiàn)代瀏覽器。

不過(guò)好在 Dynamic imports 特性是可以有 Polyfill 的:也就是說(shuō)食茎,只要你想蒂破,它也可以運(yùn)行在相對(duì)低版本的瀏覽器中。

打包 or 不打包

隨著Vite 的出現(xiàn)别渔,引發(fā)了另外一個(gè)值得我們思考的問(wèn)題:究竟還有沒(méi)有必要打包應(yīng)用附迷?

畢竟在它之前,我們使用 Webpack 打包應(yīng)用代碼哎媚,使之成為一個(gè) bundle.js喇伯,主要有兩個(gè)原因:
1、瀏覽器環(huán)境并不支持模塊化
2拨与、零散的模塊文件會(huì)產(chǎn)生大量的 HTTP 請(qǐng)求
隨著瀏覽器的對(duì) ES 標(biāo)準(zhǔn)支持的逐漸完善稻据,第一個(gè)問(wèn)題已經(jīng)慢慢不存在了。現(xiàn)階段絕大多數(shù)瀏覽器都是支持 ES Modules 的买喧。
零散模塊文件確實(shí)會(huì)產(chǎn)生大量的 HTTP 請(qǐng)求捻悯,而大量的 HTTP 請(qǐng)求在瀏覽器端就會(huì)并發(fā)請(qǐng)求資源的問(wèn)題;
在并行請(qǐng)求時(shí)淤毛,排在后面的請(qǐng)求就因?yàn)橛蛎溄訑?shù)已超過(guò)限制今缚,而被掛起等待了一段時(shí)間。

在 HTTP 1.1 的標(biāo)準(zhǔn)下低淡,每次請(qǐng)求都需要單獨(dú)建立 TCP 鏈接姓言,經(jīng)過(guò)完整的通訊過(guò)程瞬项,非常耗時(shí);

image

而且每次請(qǐng)求除了請(qǐng)求體中的內(nèi)容何荚,請(qǐng)求頭中也會(huì)包含很多數(shù)據(jù)滥壕,大量請(qǐng)求的情況下也會(huì)浪費(fèi)很多資源。

但是這些問(wèn)題隨著 HTTP 2 的出現(xiàn)兽泣,也就不復(fù)存在了绎橘。

image.png

在 HTTP/2 中,有了二進(jìn)制分幀之后唠倦,HTTP /2 不再依賴 TCP 鏈接去實(shí)現(xiàn)多流并行了称鳞,在 HTTP/2 中:

同域名下所有通信都在單個(gè)連接上完成。
單個(gè)連接可以承載任意數(shù)量的雙向數(shù)據(jù)流稠鼻。
數(shù)據(jù)流以消息的形式發(fā)送冈止,而消息又由一個(gè)或多個(gè)幀組成,多個(gè)幀之間可以亂序發(fā)送候齿,因?yàn)楦鶕?jù)幀首部的流標(biāo)識(shí)可以重新組裝熙暴。
這一特性,使性能有了極大提升:

同個(gè)域名只需要占用一個(gè) TCP 連接慌盯,使用一個(gè)連接并行發(fā)送多個(gè)請(qǐng)求和響應(yīng),消除了因多個(gè) TCP 連接而帶來(lái)的延時(shí)和內(nèi)存消耗周霉。
并行交錯(cuò)地發(fā)送多個(gè)請(qǐng)求,請(qǐng)求之間互不影響亚皂。
并行交錯(cuò)地發(fā)送多個(gè)響應(yīng)俱箱,響應(yīng)之間互不干擾。
在 HTTP/2 中灭必,每個(gè)請(qǐng)求都可以帶一個(gè) 31bit 的優(yōu)先值狞谱,0 表示最高優(yōu)先級(jí), 數(shù)值越大優(yōu)先級(jí)越低禁漓。有了這個(gè)優(yōu)先值跟衅,客戶端和服務(wù)器就可以在處理不同的流時(shí)采取不同的策略,以最優(yōu)的方式發(fā)送流播歼、消息和幀伶跷。

特性小結(jié)

Vite 帶來(lái)的優(yōu)勢(shì)主要體現(xiàn)在提升開(kāi)發(fā)者在開(kāi)發(fā)過(guò)程中的體驗(yàn)。

1荚恶、Dev Server 無(wú)需等待撩穿,即時(shí)啟動(dòng)磷支;
2谒撼、幾乎實(shí)時(shí)的模塊熱更新;
3雾狈、所需文件按需編譯廓潜,避免編譯用不到的文件;
4、開(kāi)箱即用辩蛋,避免各種 Loader 和 Plugin 的配置呻畸;
TypeScript - 內(nèi)置支持
less/sass/stylus/postcss - 內(nèi)置支持(需要單獨(dú)安裝所對(duì)應(yīng)的編譯器)
Vite 的核心功能:Static Server + Compile + HMR

核心思路:

1、將當(dāng)前項(xiàng)目目錄作為靜態(tài)文件服務(wù)器的根目錄
2悼院、攔截部分文件請(qǐng)求
3伤为、處理代碼中 import node_modules 中的模塊
4、處理 vue 單文件組件(SFC)的編譯
5据途、通過(guò) WebSocket 實(shí)現(xiàn) HMR

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绞愚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子颖医,更是在濱河造成了極大的恐慌位衩,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熔萧,死亡現(xiàn)場(chǎng)離奇詭異糖驴,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)佛致,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)贮缕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人俺榆,你說(shuō)我怎么就攤上這事跷睦。” “怎么了肋演?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵抑诸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我爹殊,道長(zhǎng)蜕乡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任梗夸,我火速辦了婚禮层玲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘反症。我一直安慰自己辛块,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布铅碍。 她就那樣靜靜地躺著润绵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胞谈。 梳的紋絲不亂的頭發(fā)上尘盼,一...
    開(kāi)封第一講書(shū)人閱讀 49,950評(píng)論 1 291
  • 那天憨愉,我揣著相機(jī)與錄音,去河邊找鬼卿捎。 笑死配紫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的午阵。 我是一名探鬼主播躺孝,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼底桂!你這毒婦竟也來(lái)了括细?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤戚啥,失蹤者是張志新(化名)和其女友劉穎奋单,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體猫十,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡览濒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拖云。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贷笛。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宙项,靈堂內(nèi)的尸體忽然破棺而出乏苦,到底是詐尸還是另有隱情,我是刑警寧澤尤筐,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布汇荐,位于F島的核電站,受9級(jí)特大地震影響盆繁,放射性物質(zhì)發(fā)生泄漏掀淘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一油昂、第九天 我趴在偏房一處隱蔽的房頂上張望革娄。 院中可真熱鬧,春花似錦冕碟、人聲如沸拦惋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)厕妖。三九已至,卻和暖如春我衬,著一層夾襖步出監(jiān)牢的瞬間叹放,已是汗流浹背饰恕。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工挠羔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留井仰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓破加,卻偏偏與公主長(zhǎng)得像俱恶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子范舀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • 1.創(chuàng)建一個(gè)vite項(xiàng)目 或者 2.vite簡(jiǎn)介 vite 是一個(gè)基于 Vue3 單文件組件的非打包開(kāi)發(fā)服務(wù)器合是,它...
    前端優(yōu)選閱讀 42,956評(píng)論 1 19
  • 1.Vue 知識(shí)體系 1.1 基礎(chǔ)原理1.1.1 Vnode Vnode也稱虛擬node節(jié)點(diǎn),是對(duì)真實(shí)元素的抽象。...
    牛課科技閱讀 423評(píng)論 0 1
  • 從0開(kāi)始理解Vite的主要新特性(一) - 因卓誒-愛(ài)分享愛(ài)原創(chuàng)的技術(shù)博客 ~ 個(gè)人博客[https://www....
    因卓誒閱讀 1,108評(píng)論 0 4
  • 隨著現(xiàn)代前端開(kāi)發(fā)的復(fù)雜度和規(guī)模越來(lái)越龐大锭环,已經(jīng)不能拋開(kāi)工程化來(lái)獨(dú)立開(kāi)發(fā)了聪全,如react的jsx代碼必須編譯后才能在...
    coderfl閱讀 252評(píng)論 0 0
  • 2020年太難了,終于等到元旦能放假休息幾天辅辩,閑著沒(méi)事逛微博难礼,然后,收到了來(lái)自米國(guó)的禮物:Vite2.0玫锋; 有沒(méi)有...
    西嶺老濕閱讀 956評(píng)論 0 1