Webpack介紹
TL;DRWebpack 4 大核心概念:entry(入口)/output(輸出)/loader(處理檔案)/plugin(進階任務)。2026 年 Webpack 已被 Vite / Rspack / Turbopack / esbuild 大幅取代,新專案直上 Vite(Vue 系)或 Rspack(Rust 寫的 Webpack 相容)。本筆記內容仍是經典理論,值得讀懂。
當前 Web 開發中,模組化已經變得越來越重要,並且使用許多不同的技術和框架。webpack 是一個現代的 JavaScript 模組化解決方案,它可以將應用程式的資源打包在一起,以提高應用程式的性能和效率。下面是一些有關 webpack 的介紹:
Webpack的好處
-
模組化:Webpack 可以將整個應用程式拆分為多個模組,每個模組可以獨立開發、測試和管理。同時,Webpack 還可以自動解決模組之間的相互依賴關係,讓開發者不用手動處理。
-
資源優化:Webpack 可以將多個 CSS、JavaScript 和圖片等資源打包到一個或多個檔案中,從而減少網頁請求次數,提高網頁載入速度。同時,Webpack 還可以對這些資源進行壓縮、優化等處理,從而減少檔案大小,提高網頁性能。
-
開發效率:Webpack 可以自動重新打包和刷新網頁,從而減少開發者手動重載網頁的時間,提高開發效率。
-
共同環境:Webpack 可以提供一個統一的開發和部署環境,從而讓開發者可以更方便地進行協作和部署。
什麼是 webpack?
webpack 是一個模組打包工具,它能夠解析應用程式的依賴關係,並根據依賴關係將所有資源打包成一個或多個 Bundle。 Bundle 是一個包含應用程式的所有 JavaScript、CSS、HTML 檔案的檔案。
Bundle又是什麼?
在 Web 開發中,Bundle(捆綁包)是一個將多個檔案合併為一個檔案的過程。Bundle 的目的是減少網頁載入時間,提高網頁性能。
在使用 Webpack 時,一個 Bundle 指的是將多個 JavaScript、CSS、圖片等檔案合併到一個或多個 JavaScript 檔案中。Webpack 會根據應用程式中使用的模組來自動建立 Bundle。當使用者訪問網頁時,瀏覽器只需要載入一個 Bundle 檔案,而不需要載入多個獨立的檔案,從而提高網頁載入速度和性能。
Bundle 可以被視為一個打包的檔案,其中包含了應用程式中所有需要的資源。它可以是一個 JavaScript 檔案、一個 CSS 檔案、一個圖片檔案,或者是多個檔案的組合。Bundle 的建立是透過 Webpack 的模組打包系統實現的。在建立 Bundle 時,Webpack 會解析應用程式中使用的模組,並建立一個依賴圖(Dependency Graph)。Webpack 根據依賴圖將所有需要的模組打包成一個或多個 Bundle 檔案。
簡單來說,Bundle 就是將多個檔案打包成一個或多個檔案的過程,通常用於減少網頁載入時間和提高網頁性能。在 Webpack 中,Bundle 是透過模組打包系統建立的。
為什麼要使用 webpack?
webpack 允許您使用許多不同的前端工具,例如:JSX、CSS、Sass、TypeScript、ES6 等。這些工具通常不支援直接在瀏覽器上執行,因此 webpack 可以將它們轉換為可執行的檔案。
此外,webpack 還具有優化功能,例如:代碼分割、按需加載、壓縮、優化圖像等等。這些優化功能能夠提高應用程式的性能和速度。
如何使用 webpack?
使用 webpack 的第一步是安裝 webpack 和相關的 loader 或 plugin。loader 負責將不同的資源轉換為 JavaScript 代碼,而 plugin 則能夠進一步優化這些代碼。
接下來,您需要為應用程式配置 webpack。webpack 的配置是一個 JavaScript 物件,包含一個或多個配置選項,例如:入口點、輸出路徑、loader 和 plugin 等等。
最後,您可以使用 webpack 命令進行打包。webpack 命令會讀取您的配置文件,並根據配置打包您的應用程式。
webpack 的核心概念
webpack 的核心概念包括:
-
Entry:指定應用程式的入口點。
-
Output:指定打包後的檔案輸出路徑和檔案名稱。
-
Loader:將不同的資源轉換為 JavaScript 代碼。
-
Plugin:進一步優化打包後的 JavaScript 代碼。
-
Mode:指定 webpack 的工作模式(開發模式或生產模式)。
-
Bundle:包含應用程式的所有 JavaScript、CSS、HTML 檔案
無論您的網頁是只有前端還是前後端分離,您只需要使用一個 webpack。
webpack 可以根據您的配置,打包所有相關的資源為一個或多個 Bundle。
在打包前端應用程式時,您可以將應用程式的入口點設置為前端應用程式的主 JavaScript 檔案。webpack 將會解析這個 JavaScript 檔案,並搜尋所有相關的資源(例如:CSS、圖像、字體等等),並將它們打包成一個或多個 Bundle。
如果您的網頁是前後端分離的,您可以使用不同的入口點和輸出路徑設置,將前端和後端的程式碼打包為不同的 Bundle。這樣可以使得前後端的程式碼分離,方便維護和部署。
總之,webpack 是一個強大的模組打包工具,可以將您的應用程式打包成 Bundle,並提高應用程式的性能和效率。您可以根據您的需求設置入口點、輸出路徑、loader 和 plugin 等配置,打包所有相關的資源,並得到一個或多個 Bundle。
TypeScript React 版本
webpack.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/index.tsx",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "public", "dist"),
},
devServer: {
// static: 設置webpack-dev-server提供靜態資源的目錄,該選項可以接收一個對象或一個字符串
// 對象的鍵表示提供的資源的路徑,值表示對應的資源的路徑,字串表示提供的資源的路徑。
static: path.join(__dirname, "public"),
compress: true,
port: 3000,
hot: true, // 啟用 HMR 功能
},
plugins: [
new webpack.HotModuleReplacementPlugin(), // 使用 HMR 插件
],
};
tsconfig.json
{
"compilerOptions": {
"target": "ES2016",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx",
"noImplicitAny": false,
"sourceMap": true,
"declaration": true,
"outDir": "./dist",
"rootDir": "./src"
},
"include": [
"src"
]
}
package.json
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.14",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"gh-pages": "^5.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.2",
"react-scripts": "^5.0.1",
"react-uuid": "^2.0.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
"start": "webpack serve --mode development --open",
"build": "webpack --mode production",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.21.0",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
"babel-loader": "^9.1.2",
"css-loader": "^6.7.3",
"style-loader": "^3.3.1",
"ts-loader": "^9.3.1",
"typescript": "^4.9.5",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}
}
JavaScript版本
假設您正在開發一個簡單的網站,其中包含一個 HTML 檔案和一個 JavaScript 檔案。JavaScript 檔案是您的應用程式的入口點。您還有一個 CSS 檔案,需要將其打包成一個 Bundle,以便於在網頁中使用。
步驟1:安裝 webpack
請先確保已經安裝了 Node.js 和 npm。在命令行中,輸入以下命令來安裝 webpack:
npm install webpack webpack-cli --save-dev
步驟2:建立項目
在您的項目目錄中,建立一個名為 **src** 的資料夾,並在其中建立以下檔案:
- index.html
- index.js
- styles.css
在 **index.html** 中,添加以下內容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack Example</title>
<link rel="stylesheet" href="dist/styles.css">
</head>
<body>
<h1>Hello, World!</h1>
<script src="dist/main.js"></script>
</body>
</html>
在 **index.js** 中,添加以下內容:
javascriptCopy code
console.log('Hello, World!');
在 **styles.css** 中,添加以下內容:
h1 {
color: blue;
}
步驟3:建立 webpack 配置檔
在您的項目目錄中,建立一個名為 **webpack.config.js** 的檔案,添加以下內容:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
],
},
};
這個配置檔告訴 webpack:
-
使用
**./src/index.js**作為入口點。 -
將打包後的 JavaScript 檔案命名為
**main.js**,並將其儲存在**dist**資料夾中。 -
使用
**css-loader**和**style-loader**,處理**css**檔案,將其打包到**main.js**中。
步驟4:打包應用程式
在命令行中,輸入以下命令來打包應用程式:
npx webpack
這會生成一個名為 **main.js** 的 Bundle,並將其儲存在 **dist** 資料夾中。此外,CSS 檔案也會被打包到 **main.js** 中。
步驟5:在網頁中引入 Bundle
在 **index.html** 中,已經引入了 **main.js**,現在可以在網頁中使用 JavaScript 了。同時,由於 **styles.css** 已經打包到了 **main.js** 中,因此可以直接在 **index.html** 中引入。
打開 **index.html**,您應該可以看到一個藍色的 "Hello, World!" 標題。這表示您已經成功地打包了應用程式!
TypeScript版本
假設您已經安裝了 TypeScript 和 Webpack。接下來,您可以創建一個名為 **tsconfig.json**
的 TypeScript 配置檔,並將以下內容添加到其中:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true
}
}
然後,創建一個名為 **index.ts** 的 TypeScript 檔案,並在其中添加以下內容:
class Greeter {
private greeting: string;
constructor(message: string) {
this.greeting = message;
}
public greet(): string {
return `Hello, ${this.greeting}!`;
}
}
const greeter = new Greeter('TypeScript');
console.log(greeter.greet());
接下來,創建一個名為 **webpack.config.js** 的 Webpack 配置檔,並將以下內容添加到其中:
const path = require('path');
module.exports = {
entry: './index.ts',
devtool: 'inline-source-map',
mode: 'development',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
這個配置檔告訴 Webpack:
-
使用
**./index.ts**作為入口點。 -
使用
**ts-loader**,處理**.ts**和**.tsx**檔案,將其轉換為 JavaScript。 -
使用
**inline-source-map**生成 sourcemap,以方便調試。 -
將打包後的 JavaScript 檔案命名為
**bundle.js**,並將其儲存在**dist**資料夾中。
最後,在命令行中輸入以下命令來打包應用程式:
npx webpack
這會生成一個名為 **bundle.js** 的 Bundle,並將其儲存在 **dist** 資料夾中。現在,您可以在網頁中引入 **bundle.js**,並使用 TypeScript 撰寫的代碼。
般來說在開發 TypeScript 應用程式時,會使用 Webpack 將 **.ts** 和 **.tsx** 檔案轉換為 JavaScript 檔案,以便在瀏覽器中運行。
使用 TypeScript 的主要目的是為了讓代碼更具可讀性、可維護性和可靠性,而不是為了運行在瀏覽器中。TypeScript 代碼在編譯後會產生 JavaScript 代碼,這些代碼可以運行在瀏覽器中或其他執行環境中。
在開發 TypeScript 應用程式時,您可以利用 TypeScript 提供的型別檢查、自動完成和錯誤提示等功能,從而減少代碼中的錯誤和漏洞。然後,使用 Webpack 將 TypeScript 代碼轉換為 JavaScript 代碼,以便在瀏覽器中運行。
因此,使用 Webpack 將 TypeScript 代碼轉換為 JavaScript 代碼並不會影響您使用 TypeScript 的目的。相反,它可以幫助您更好地開發 TypeScript 應用程式,並提高代碼的可靠性和可維護性。
JavaScript教學 第二版
Step 1. 安裝 Node.js 首先,你需要在你的電腦上安裝 Node.js,可以到 Node.js 官網下載並安裝。
Step 2. 創建新的專案資料夾 在你的電腦上創建一個新的資料夾,並在其中創建一個 package.json 文件,可以使用以下命令進行創建:
mkdir my-project
cd my-project
npm init -y
這個命令將在 my-project 資料夾中創建一個 package.json 文件,其中 -y 表示使用默認配置。
Step 3. 安裝 Webpack 和相關的 loader 使用 npm 安裝 Webpack 和一些必要的 loader,例如 babel-loader、css-loader 和 style-loader。可以使用以下命令進行安裝:
npm install webpack webpack-cli --save-dev
npm install babel-loader @babel/core @babel/preset-env --save-dev
npm install css-loader style-loader --save-dev
-
**webpack**和**webpack-cli**是 Webpack 的核心依賴項,用於打包和執行命令。 -
**babel-loader**、**@babel/core**和**@babel/preset-env**用於處理 ES6 以上的 JavaScript 代碼,將其轉換成瀏覽器可識別的代碼。 -
**css-loader**和**style-loader**用於處理 CSS 和樣式等資源。
Step 4. 創建 Webpack 配置文件 在項目資料夾中創建一個 webpack.config.js 文件,這個文件用於配置 Webpack。可以使用以下程式碼進行創建:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
這個配置文件中定義了入口檔案、輸出檔案、loader 和插件等屬性。其中,entry 屬性定義了入口檔案,output 屬性定義了輸出檔案的位置和名稱,module 屬性定義了使用的 loader。
Step 5. 創建入口檔案和資源檔案 在 src 資料夾中創建一個 index.js 檔案,並在其中編寫 JavaScript 代碼。同時,在 src 資料夾中創建一個 styles.css 檔案,並在其中編寫 CSS 代碼,例如:
// index.js
import './styles.css';
const element = document.createElement('div');
element.innerHTML = 'Hello, World!';
document.body.appendChild(element);
/* styles.css */
body {
background-color: \#f0f0f0;
}
div {
font-size: 24px;
color: #333;
margin: 10px;
padding: 20px;
background-color: \#fff;
border: 1px solid \#ccc;
}
這裡的 index.js 使用 ES6 的模組系統,引入了 styles.css 檔案,並在其中創建了一個 div 元素。
Step 6. 執行 Webpack 打包 使用以下命令執行 Webpack 打包:
npx webpack --mode development
這個命令將會將入口檔案和資源檔案打包到一個名為 bundle.js 的檔案中。在這個例子中,輸出的 bundle.js 檔案將會被放置到 dist 資料夾中。
這就是使用 Webpack 的基本步驟。通過配置 Webpack 配置文件,你可以將不同的資源文件進行打包,從而優化你的前端項目。
打包JS模組
首先,我們有兩個模組:**module1.js**和**module2.js**。它們分別包含了一些函數和變數。
**module1.js**:
export const foo = () => {
console.log("Hello from module 1");
};
export const bar = () => {
console.log("Goodbye from module 1");
};
**module2.js**:
export const baz = () => {
console.log("Hello from module 2");
};
export const qux = () => {
console.log("Goodbye from module 2");
};
現在,我們想將這兩個模組打包到一個文件中。我們使用Webpack來實現這一點。
首先,我們需要安裝Webpack:
npm install webpack webpack-cli --save-dev
接下來,我們需要創建一個Webpack配置文件。我們可以在項目根目錄中創建一個名為**webpack.config.js**的文件,並在其中添加以下代碼:
const path = require("path");
module.exports = {
entry: {
module1: "./src/module1.js",
module2: "./src/module2.js"
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
}
};
這個配置文件告訴Webpack,我們有兩個入口文件(即**module1.js**和**module2.js**),它們將被打包到一個名為**[name].js**的文件中,其中**[name]**將被替換為入口文件的名稱。打包後的文件將被放在**dist**目錄中。
現在,我們可以運行Webpack了:
npx webpack
Webpack將開始打包我們的模組,並將它們放入**dist**目錄中。在這個目錄中,我們將找到**module1.js**和**module2.js**兩個文件,它們包含了我們的模組。
最後,我們可以在**index.html**中引入這兩個文件,並在JavaScript中使用這些模組:
<!DOCTYPE html>
<html>
<head>
<title>Webpack Example</title>
</head>
<body>
<script src="dist/module1.js"></script>
<script src="dist/module2.js"></script>
<script>
foo(); // logs "Hello from module 1"
bar(); // logs "Goodbye from module 1"
baz(); // logs "Hello from module 2"
qux(); // logs "Goodbye from module 2"
</script>
</body>
</html>
如此,我們就成功地將兩個模組打包到一個文件中,並在JavaScript中使用它