cover

你寫了 50 個 JS 檔案,難道要在 HTML 裡面放 50 個 <script> 嗎?打包工具解決的就是這個問題——以及更多你沒想到的問題。

先講結論

打包工具做三件事:把散落的模組合成少數幾個檔案(減少 HTTP 請求)、把新語法轉成舊瀏覽器能跑的(相容性)、把程式碼壓縮到最小(效能)。新專案用 Vite,舊專案繼續用 Webpack,開發套件用 Rollup。

沒有打包工具的痛

模組化問題

早期 JavaScript 沒有模組系統,所有東西都丟全域:

<script src="jquery.js"></script>
<script src="utils.js"></script>      <!-- 依賴 jquery -->
<script src="component.js"></script>  <!-- 依賴 utils -->
<script src="app.js"></script>        <!-- 依賴全部 -->

順序不能錯——錯了就爆。全域變數互打——utils 裡的 formatDate 可能跟 component 裡的撞名。依賴關係只存在你的腦子裡——新人接手完全看不出來誰依賴誰。

有了模組系統和打包工具:

import { formatDate } from './utils.js';
import React from 'react';

依賴關係清清楚楚,打包工具自動分析依賴樹、決定載入順序、合併成最終產物。

瀏覽器相容性

你用 arrow function、optional chaining、async/await 寫得很開心,但使用者的 IE 11(或某些企業內部的古董瀏覽器)看到這些語法直接白屏。打包工具搭配 Babel 可以把新語法轉成舊瀏覽器能跑的 ES5。

效能問題

50 個 JS 檔案 = 50 個 HTTP 請求。在 HTTP/1.1 的時代,瀏覽器同時只能開 6 個連線,光是等下載就要等到天荒地老。打包成一個(或少數幾個)檔案,請求次數大幅減少。再加上壓縮(minify),5MB 的原始碼可以壓到 500KB。

Webpack vs Vite:為什麼 Vite 這麼快

Webpack 開發模式: 啟動 → 把所有檔案打包一遍 → 啟動 Dev Server → 你等了 30 秒

Vite 開發模式: 啟動 → 直接啟動 Dev Server → 你打開頁面時才編譯需要的檔案 → 毫秒級

Vite 利用瀏覽器原生支援的 ES Modules——開發時不打包,直接把 import 丟給瀏覽器處理。只有在生產環境才用 Rollup 做完整打包。

// vite.config.js — 設定比 Webpack 簡單很多
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
 
export default defineConfig({
  plugins: [react()],
  server: { port: 3000 },
});

對比 Webpack 的 config,Vite 的設定檔大概只有它的 1/5。Webpack 的 config 寫到你懷疑自己不是在寫前端。

打包工具幫你做的優化

Code Splitting:按需載入

const Dashboard = lazy(() => import('./Dashboard'));
const Settings = lazy(() => import('./Settings'));

使用者進首頁只載入首頁的 code,點到設定頁才載入設定頁的 code。不用一次下載整個 App 的所有程式碼。

Tree Shaking:刪掉沒用到的 code

// utils.js 匯出了 10 個函式
export function used() { ... }
export function unused() { ... }  // 沒人 import → 不會被打包

你引入了一個 lodash 但只用了 _.debounce?Tree shaking 確保最終 bundle 只包含你實際用到的部分。

Minification:壓到最小

// 壓縮前
function calculateTotal(items) {
  let total = 0;
  for (const item of items) {
    total += item.price * item.quantity;
  }
  return total;
}
 
// 壓縮後
function calculateTotal(t){let e=0;for(const n of t)e+=n.price*n.quantity;return e}

變數名縮短、空白刪除、註解移除。機器讀得懂就好,不需要人類可讀。

該選哪個?

新專案            → Vite(快、設定簡單)
舊專案維護        → 繼續用 Webpack(沒必要為了換工具重構)
開發 npm 套件     → Rollup(tree shaking 最好)
什麼都不想設定    → Parcel(零設定)

什麼時候不需要打包工具?簡單靜態網頁、用 CDN 載入的小型原型。但只要你用到 npm 套件 + 框架,打包工具基本上是必要的。


打包工具就像洗碗機——你可以手洗,但當碗多到一定程度,你就會慶幸有這個東西。


延伸閱讀

Vite 官方文件 Webpack 官方文件 工程化 NPM 基本指令 前後端分離 - 序章