為什麼前端不愛用 Webpack 了? Vite 簡介

閱讀時間約 9 分鐘

Vite 是由 Vue 開發者 Evan You 所開發出來,用來加快、優化程式碼打包的工具,在這裡我們不免會需要提到大部分前端開發者可能都會聽過、使用過的前端工具:Webpack。

在那之前,我們先來聊聊為什麼前端會需要所謂的打包工具呢?

在 ES6 釋出前,有一段前端社群大亂鬥的年代,在那段時間沒有所謂「官方的模組化」技術,各家實作前端技術的標準不一,或是當前端有了新的技術,瀏覽器卻沒有支援的窘境,為了要讓開發者所寫的各式各樣程式碼能在瀏覽器端更有效率及更相容地運行,就有了所謂打包工具。

在過往,我們會使用 Webpack 這個工具來打包在正式環境所需要的程式碼,簡單概括 Webpack 的一些機制:

  • Webpack 是一個模組打包工具,用來解決瀏覽器載入程式碼所遇到的一些問題,多框架底層也應用了 webpack,例如:React、Angular 等。
  • Webpack 會透過使用者自定義的進入點來進行打包,這個進入點可以透過引入的方式指向其他模組,在這個過程中,webpack 會依照我們所引入的模組產生相依圖(Dependency Graph),再根據設定檔產出最後的結果,透過定義分割點(split points),webpack 可以將檔案切割成多個塊狀(chunks)。
  • Webpack 支援 ESM、CommonJS、MJS、AMD 等模組,同時也支援 WebAssembly 技術(將 JavaScript 轉譯成 C++ 這種機器語言,優化運行效能的技術)。

Webpack 除了上述的特點外,有幾個為人所詬病的缺點:

  • 打包速度慢
  • 近代的瀏覽器已經支援 ESM 這個原生的模組載入技術,不像一、二十年前瀏覽器實作技術跟不上 ECMA Script 規範,需要將新的語法透過 Babel 搭配 Webpack 轉譯為瀏覽器所看到的語言,不再需要支援舊的語法
  • 配置複雜,學習曲線高
  • 較適合大型的專案,對中小型專案來說有點大材小用

簡而言之,現有的打包技術不敷使用造就了 Vite 的崛起。

快還要再快的 Vite

為了優化 Webpack 的執行速度,Vite 有了以下特色:

  • 使用瀏覽器原生的 ESM 動態加載,去掉過往針對 CommonJS、MJS、AMD 等模組的支援
  • 針對 TypeScript 去掉 Type Check 的過程,交給 IDE(例如:VS code) 工具來解決
  • 將程式碼拆分為相依模組(Dependencies)與 原始碼(Source Code)兩種類型,相依模組為純 JavaScript,像是一些會需要花很多資源處理,但在開發過程中不怎麼會變動內容的 JavaScript 大型函式庫,Vite 透過 esbuild 工具針對這些相依模組進行預先打包(pre-bundle dependencies),這個機制使用 Go 來進行打包,執行速度為 JavaScript-based 打包加快 10-100 倍。
  • 而原始碼為非純 JavaScript 的程式碼,例如:JSX、CSS 或是 Vue 元件等,這類型的程式碼會在開發過程中不斷編輯,但並不會同時載入,所以會使用 route-based 或是 code-spliting 的方式來動態加載這些程式碼。Vite 在這邊會使用原生的 ESM 來載入這些原始碼,在這個部分 Vite 會讓瀏覽器接手原本屬於打包工具的任務,Vite 只需要在瀏覽器針對特定原始碼進行請求時,將原始碼進行轉換及提供程式碼給瀏覽器。Vite 可以把 ESM 本身看作是獨立的 Chunks 進行拆分載入,使用原生瀏覽器的狀況下就能實踐動態載入,降低打包工具在 Build 過程時的時間。Vite 與其他打包工具的差異可以透過下圖簡單了解,透過 Vite 我們可以減少過往開發時,產生新的 Bundle 或是 Chunks 花不少時間等待新的打包檔的產生的過程,除了減少打包過程的時間,Vite 的 HMR 也會基於原生 ESM 的關係比其他打包工具快上不少:
raw-image
raw-image


瀏覽器相容性

由於 Vite 原生的 ESM ,對於支援性較差的瀏覽器來說,以往我們會在使用一些打包工具時,在指定的生命週期使用 Babel 將一些 ES6 以後的語法編譯成相容性較好的程式碼。

不過 Vite 官方提供 @vitejs/plugin-legacy 插件來快速處理瀏覽器相容的問題,可以將這個插件想像成強化版的 Babel 來做使用。

講了那麼多,接著我們就來使用 Vite 快速啟動環境吧:

Vite 安裝流程

Vite 官方要求使用 14.18 以上的 node 版本,因為 Vite 支援多前端框架的模板(vanilla、vue、react、preact、lit、svetle 與其對應的 typeScript 模板),所以在使用較新的前端框架時,可能會需要使用更新版本的 node.js。

  • 使用 NPM:
$ npm create vite@latest
  • 使用 yarn
$ yarn create vite
  • 使用 pnpm
pnpm create vite

接著就會出現一些提示文字,選取你所需要的模板就會獲得你所需要的框架模板,或者是可以使用以下指令獲得指定的版本:

# npm 6.x
$ npm create vite@latest my-react-ts-app --template react-ts

# npm 7+, extra double-dash is needed:
$ npm create vite@latest my-react-ts-app -- --template react-ts

# yarn
$ yarn create vite my-react-ts-app --template react-ts

# pnpm
$ pnpm create vite my-react-ts-app --template react-ts

Vite 指令介面(CLI)

當你安裝好 vite 模板後,可以在 package.json 中看到 vite 預設幫我們寫好的指令介面:

{
"scripts": {
"dev": "vite", // 啟動本地 server
"build": "vite build", // 打包正式環境程式碼
"preview": "vite preview" // 預覽打包好的正式環境程式碼
}
}

如果想要知道有哪一些指令可以使用,可以使用以下指令查詢:

$ npx vite --help

Vite 進階功能介紹

了解了基本的安裝與其爆紅的原因後,來了解一下 Vite 還有一些什麼樣的配置與功能:

NPM 依賴解析和預打包

原生的 ESM 其實並不支援所謂的裸模組(Bare Module import)的引入,舉例來說,下方這種引入模組的方式如果未經處理,直接丟到瀏覽器的話是沒有辦法運行的:

import { someMethod } from 'my-dep'; // bare module import 

如果要使用裸模組來加載模組的話,通常要仰賴第三方的套件或是進行額外的配置才有辦法使用,但 Vite 本身幫我們預先處理好了裸模組配置:

  1. 透過以 Go 為底層的 EsBuild 進行預打包,提前將 CommonJS / UMD 轉為 ESM,提升頁面的載入速度。
  2. 改寫裸模組路徑為絕對路徑,讓瀏覽器看得懂

Hot Module Replacement

Vite 自帶以 ESM 為基礎的 HMR 機制,可以在不重新刷頁面的狀況下,僅載入有被更新的模組,相較於 Webpack 的 HMR ,在開發速度加快不少。

TypeScript

Vite 在 TypeScript 上有一些不一樣的處理方式,由於 TypeScript 是一種靜態的語言,要檢查型別是否正確會是在程式碼在編譯階段時檢查,由於 TypeScript 的型別檢查會需要整體模組圖(module gragh)沒辦法像 ESM 一樣以模組作為單位來檢查,這與 Vite 的設計風格有所衝突。

因此 Vite 不會針對 TypeScript 去做型別的檢查,而是將這個工作交給 IDE 完成,例如:IDE 的 Typescript 檢查插件,或是我們可以透過第三方工具,例如: ESLint,來協助靜態型別的檢查。

不過 Vite 本體本身雖然不支援編譯時的型別檢查,但還是有提供額外的擴充讓開發者依然可以進行型別檢查。

CSS

Vite 支援大部分主流的 CSS 工具,例如:原生 CSS 、PostCSS、CSS modules,也可以額外使用其他預處理器:SASS、SCSS 等,我們可以在 vite.config.js 針對專案的需要進行配置。

  • 原生 CSS:
import "./index.css";

會直接將引入的 CSS 文件內容複製一份,生成 <style> 標籤後丟到 <head> 標籤中,引入幾個檔案就丟幾個 <style> ,因此在不經處理的狀況下原生的 CSS 會有全域污染、覆蓋的問題,所以通常會搭配 CSS Modules 取得獨一無二的選擇器名稱。

SVG 的載入

在 Vite React 專案中,我們可以使用 @vite-plugin-svgr 這個擴充插件,讓我們把 svg 作為一個 React Component 使用,可以透過以下指令安裝這個套件:

  • 使用 NPM:
$ npm i vite-plugin-svgr

在 Vite 設定檔載入這個插件:

// vite.config.js
import svgr from 'vite-plugin-svgr'

export default {
// ...
plugins: [svgr()],
}

就可以透過以下的方式載入 svg 檔囉:

import { ReactComponent as Logo } from './logo.svg'


參考資料:Vitejs


關於我:

一名從英文系畢業的前端工程師,喜歡閱讀、寫東西及自我成長。

|Instagram: Vivian Yeh|vivian_enlife

|聯絡我:[email protected]

為了追求可以窩在座位上、可以心無旁騖思考問題、座位可以亂七八糟沒關係、不需要到處哈腰點頭跑客戶,不用腳踩十公分、連妝都可以不用化的職場人生,文組少女毅然決然踏上RD的養成日常。
留言0
查看全部
發表第一個留言支持創作者!
上一篇文章分享了 TypeScript 的定義、前端角色定位,如果你不是很確定「TypeScript 是什麼?」、「TypeScript 作為 JavaScript 的超集,在網頁開發扮演怎麼樣的角色?」這兩個問題的答案,建議可以回到上一篇先了解一下。
在前端的開發中,除了切版與串 API 外,大部分的時間都在針對表單內容進行檢核、驗證、阻擋,一方面是讓使用者在操作頁面的過程中有良好的使用者體驗,不會因為一些例外狀況(Edge Case),例如:莫名其妙的 4xx 錯誤,導致使用者卡在某個操作流程中逃不出來,另一方面是讓傳遞到後端的資料更加正確⋯⋯
在 2021 年的剛轉職成為前端工程師的時候,我在面試時滿常會被詢問到 JavaScript 中閉包的議題,當時候自己回答的滿差的,於是在 2022 年時,我寫了一系列的有關於函式程式設計鐵人賽的文章, 裡頭就有簡單提到有關於閉包的議題。
在之前的文章當中曾經提到過 JavaScript 中的物件有一個特別的機制:傳參考(Called by reference),如果正確性再高一點的話,則可以稱之為傳共享(Called by sharing)。
在先前的型別文章中,我們曾經聊過 JavaScript 常用的一些型別,但針對布林這個型別,我們沒有做太多的解釋,原因在於布林值在 JavaScript 會有一個特殊的規則:自動轉型 。 自動轉型可說是讓 JavaScript 為弱型別、且難以管理的最重要的要素,接著就來讓我們來聊聊什麼是自動轉型
在剛開始寫 JavaScript 可能大多數的人不會特別意識到 JavaScript 的型別系統有什麼特別之處,我是在看完 Youtube 上 CS50 的課程,才理解到在不同的程式語言中,會因為語言的特性而有不同的系統,JavaScript 就是偏向比較特別的那一種。
上一篇文章分享了 TypeScript 的定義、前端角色定位,如果你不是很確定「TypeScript 是什麼?」、「TypeScript 作為 JavaScript 的超集,在網頁開發扮演怎麼樣的角色?」這兩個問題的答案,建議可以回到上一篇先了解一下。
在前端的開發中,除了切版與串 API 外,大部分的時間都在針對表單內容進行檢核、驗證、阻擋,一方面是讓使用者在操作頁面的過程中有良好的使用者體驗,不會因為一些例外狀況(Edge Case),例如:莫名其妙的 4xx 錯誤,導致使用者卡在某個操作流程中逃不出來,另一方面是讓傳遞到後端的資料更加正確⋯⋯
在 2021 年的剛轉職成為前端工程師的時候,我在面試時滿常會被詢問到 JavaScript 中閉包的議題,當時候自己回答的滿差的,於是在 2022 年時,我寫了一系列的有關於函式程式設計鐵人賽的文章, 裡頭就有簡單提到有關於閉包的議題。
在之前的文章當中曾經提到過 JavaScript 中的物件有一個特別的機制:傳參考(Called by reference),如果正確性再高一點的話,則可以稱之為傳共享(Called by sharing)。
在先前的型別文章中,我們曾經聊過 JavaScript 常用的一些型別,但針對布林這個型別,我們沒有做太多的解釋,原因在於布林值在 JavaScript 會有一個特殊的規則:自動轉型 。 自動轉型可說是讓 JavaScript 為弱型別、且難以管理的最重要的要素,接著就來讓我們來聊聊什麼是自動轉型
在剛開始寫 JavaScript 可能大多數的人不會特別意識到 JavaScript 的型別系統有什麼特別之處,我是在看完 Youtube 上 CS50 的課程,才理解到在不同的程式語言中,會因為語言的特性而有不同的系統,JavaScript 就是偏向比較特別的那一種。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
拜讀 莫力全大大的 Day02 X 為什麼要在前端做效能優化? 重點整理 & 重述 & 加一點點自己的補充
Thumbnail
  朋友们好,今天我们来谈一谈堑壕战,堑壕战在第一次世界中被经常使用,但是到了第二次世界大战就用的少了,虽然用的少,但是还是有在用的。戴上你的金丝边框眼镜,让我们来了解一下吧。   到了第二次世界大战,由于卡车和内燃机的广泛普及,堑壕战并没有在这次战争过程中占据主导地位。卡车可以让士兵快速
Thumbnail
  朋友们好,我们来谈一谈为什么希特勒在会见完佛朗哥之后,表示宁可牙齿掉3颗都不想再和佛朗哥说话了。要理解这其中的原因,我们要先看看“初代阴阳人”西班牙大元帅佛朗哥对希特勒说了什么。我在这里简单抄录一段对话,戴上你的金丝边框眼镜,让我们来了解一下吧。   希特勒:“……如果西班牙加入轴心国
Thumbnail
在英国,“对不起”可能是最常用的词。无论是为恶劣的天气感到难过,还是走路时不小心撞到对方,普通英国人都会时不时地说“对不起”。但对于阿富汗境内的86名儿童和200多名成年平民来说,恐怕我这辈子都等不及英国人的道歉了。也许他们只能得到所谓的“援助金”。阿富汗人的命在他们眼里值多少钱? 2019 年
Thumbnail
在英国,“对不起”可能是最常用的词。无论是为恶劣的天气感到难过,还是走路时不小心撞到对方,普通英国人都会时不时地说“对不起”。但对于阿富汗境内的86名儿童和200多名成年平民来说,恐怕我这辈子都等不及英国人的道歉了。也许他们只能得到所谓的“援助金”。阿富汗人的命在他们眼里值多少钱? 2019
Thumbnail
在英国,“对不起”可能是最常用的词。无论是为恶劣的天气感到难过,还是走路时不小心撞到对方,普通英国人都会时不时地说“对不起”。但对于阿富汗境内的86名儿童和200多名成年平民来说,恐怕我这辈子都等不及英国人的道歉了。也许他们只能得到所谓的“援助金”。阿富汗人的命在他们眼里值多少钱? 2019
Thumbnail
猪头皇帝但凡有一点点体恤民间疾苦的心思,但凡有一点点基本常识,就不会在这个人满为患、海陆空全方位污染的国家废除计生、鼓励生育了。
Thumbnail
第一印象 + 统计数据 大约一周前,我创建了我的Simily帐户,将我的内容重新用于 Medium 并将其发布在 Simily 上。我有四个帖子,其中两个是虚构的,两个是非虚构的。这次我赚了整整 0.64 美元。以下是我目前的统计数据: 我的 Simily.co 仪表板的屏幕截图 我的观点是:
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
拜讀 莫力全大大的 Day02 X 為什麼要在前端做效能優化? 重點整理 & 重述 & 加一點點自己的補充
Thumbnail
  朋友们好,今天我们来谈一谈堑壕战,堑壕战在第一次世界中被经常使用,但是到了第二次世界大战就用的少了,虽然用的少,但是还是有在用的。戴上你的金丝边框眼镜,让我们来了解一下吧。   到了第二次世界大战,由于卡车和内燃机的广泛普及,堑壕战并没有在这次战争过程中占据主导地位。卡车可以让士兵快速
Thumbnail
  朋友们好,我们来谈一谈为什么希特勒在会见完佛朗哥之后,表示宁可牙齿掉3颗都不想再和佛朗哥说话了。要理解这其中的原因,我们要先看看“初代阴阳人”西班牙大元帅佛朗哥对希特勒说了什么。我在这里简单抄录一段对话,戴上你的金丝边框眼镜,让我们来了解一下吧。   希特勒:“……如果西班牙加入轴心国
Thumbnail
在英国,“对不起”可能是最常用的词。无论是为恶劣的天气感到难过,还是走路时不小心撞到对方,普通英国人都会时不时地说“对不起”。但对于阿富汗境内的86名儿童和200多名成年平民来说,恐怕我这辈子都等不及英国人的道歉了。也许他们只能得到所谓的“援助金”。阿富汗人的命在他们眼里值多少钱? 2019 年
Thumbnail
在英国,“对不起”可能是最常用的词。无论是为恶劣的天气感到难过,还是走路时不小心撞到对方,普通英国人都会时不时地说“对不起”。但对于阿富汗境内的86名儿童和200多名成年平民来说,恐怕我这辈子都等不及英国人的道歉了。也许他们只能得到所谓的“援助金”。阿富汗人的命在他们眼里值多少钱? 2019
Thumbnail
在英国,“对不起”可能是最常用的词。无论是为恶劣的天气感到难过,还是走路时不小心撞到对方,普通英国人都会时不时地说“对不起”。但对于阿富汗境内的86名儿童和200多名成年平民来说,恐怕我这辈子都等不及英国人的道歉了。也许他们只能得到所谓的“援助金”。阿富汗人的命在他们眼里值多少钱? 2019
Thumbnail
猪头皇帝但凡有一点点体恤民间疾苦的心思,但凡有一点点基本常识,就不会在这个人满为患、海陆空全方位污染的国家废除计生、鼓励生育了。
Thumbnail
第一印象 + 统计数据 大约一周前,我创建了我的Simily帐户,将我的内容重新用于 Medium 并将其发布在 Simily 上。我有四个帖子,其中两个是虚构的,两个是非虚构的。这次我赚了整整 0.64 美元。以下是我目前的统计数据: 我的 Simily.co 仪表板的屏幕截图 我的观点是: