看完本篇你將基本了解webpack!!!
目錄
一、Webpack 的作用
1、基本配置結構
2、配置項詳解
1. entry —— 構建入口
2. output —— 輸出配置
3. mode:模式設置
4. module:模塊規則
5. plugins:插件機制
6. resolve:模塊解析配置(可選)
7. devServer:開發服務器(可選)
8. devtool:調試工具(可選)
9. target:目標平臺(可選)
二、構建流程
1. 初始化(Initialization)
1. 讀取配置文件
2. 初始化 Compiler 對象
3. 注冊所有插件(Plugin 注冊階段)
2. 構建模塊圖(Build Dependency Graph)
3. 模塊轉換與解析
示例 1:JS 文件(可能含 ES6、TS)
示例 2:CSS 文件
示例 3:圖片文件
4. 生成代碼塊(Chunk)與文件(Asset)
1、 Chunk(代碼塊)
常見的 Chunk 類型:
?? 舉個例子
為什么要把代碼分成多個 chunk?
1. 性能優化:
2. 緩存優化:
2、Asset(最終產出資源文件)
3. Chunk 轉換為 Asset( bundle)
4. 輸出 Asset 到 output.path
5. 輸出階段(Emit)
三、插件機制
1、插件“注冊”發生在 —— ? 初始化階段(Initialization)
2、插件“執行”發生在 —— ? 構建過程的每一個階段(Build Lifecycle)
3、compilation
1. 模塊的管理
2. 構建 Chunk
3. 生成 Asset(輸出資源)
4. Plugin 的生命周期鉤子
四、配置項之間的相互關系
1. entry 與 module.rules
2. entry 與 output
3. module.rules 與 plugins
4. mode 與其他所有配置項
5. devServer 與 output
6. plugins 與 output
五、 Loader
1、什么是 Loader?
2、為什么需要 Loader?
3、常見 Loader 類型
1、 什么是 babel-loader?
2、你為什么需要 babel-loader?
3、核心概念說明
4、常見用途
4、Webpack 如何調用 Loader?
六、構建優化與高級功能
1. 代碼分割(Code Splitting)
2. Tree Shaking
Tree Shaking 的基本原理
3. 懶加載(Lazy Loading)與預加載
1、什么是懶加載(Lazy Loading)?
Webpack 如何實現懶加載?
2、什么是預加載(Preload)和預取(Prefetch)?
1. webpackPrefetch: true → 瀏覽器空閑時加載
2. webpackPreload: true → 當前幀就加載
一、Webpack 的作用
Webpack 的主要作用是:
-
模塊打包:將多個模塊(JS、CSS、圖片等)打包成一個或多個文件。
-
代碼拆分(Code Splitting):根據需要拆分代碼,提高首屏加載速度。
-
資源處理:處理 JS 之外的資源,如 CSS、LESS、SASS、圖片、字體等。
-
開發工具支持:提供開發服務器、熱更新(HMR)、調試等功能。
-
優化性能:壓縮代碼、Tree Shaking(去除無用代碼)、懶加載等。
1、基本配置結構
// webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js', // 入口output: { // 輸出filename: 'bundle.js', // 輸出文件名path: path.resolve(__dirname, 'dist') // 輸出目錄(必須是絕對路徑)},module: { // 模塊處理規則rules: [{test: /\.css$/, // 正則匹配 .css 文件use: ['style-loader', 'css-loader'] // 使用的 loader,從右向左執行}]},plugins: [], // 插件列表mode: 'development' // 構建模式:development | production
};
在了解 Webpack 原理前,我們需要先了解幾個核心名詞的概念:
-
入口(Entry):構建的起點。Webpack 從這里開始執行構建。通過 Entry 配置能夠確定哪個文件作為構建過程的開始,進而識別出應用程序的依賴圖譜。
-
模塊(Module):構成應用的單元。在 Webpack 的視角中,一切文件皆可視為模塊,包括 JavaScript、CSS、圖片或者是其他類型的文件。Webpack 從 Entry 出發,遞歸地構建出一個包含所有依賴文件的模塊網絡。
-
代碼塊(Chunk):代碼的集合體。Chunk 由模塊合并而成,被用來優化輸出文件的結構。Chunk 使得 Webpack 能夠更靈活地組織和分割代碼,支持代碼的懶加載、拆分等高級功能。
-
加載器(Loader):模塊的轉換器。Loader 讓 Webpack 有能力去處理那些非 JavaScript 文件(Webpack 本身只理解 JavaScript)。通過 Loader,各種資源文件可以被轉換為 Webpack 能夠處理的模塊,如將 CSS 轉換為 JS 模塊,或者將高版本的 JavaScript 轉換為兼容性更好的形式(降級)。
-
插件(Plugin):構建流程的參與者。Webpack 的構建流程中存在眾多的事件鉤子(hooks),Plugin 可以監聽這些事件的觸發,在觸發時加入自定義的構建行為,如自動壓縮打包后的文件、生成應用所需的 HTML 文件等。
2、配置項詳解
1. entry
—— 構建入口
指定 Webpack 構建的起點,支持多入口配置。
entry: './src/index.js'
作用:指定 Webpack 構建的起點文件,從這個文件出發遞歸分析所有依賴。
-
默認值是
'./src/index.js'
。 -
支持單入口(字符串)和多入口(對象形式)。
多入口示例:
entry: {
app: './src/app.js',
admin: './src/admin.js'
}
?? Webpack 會為每個入口分別打包生成輸出文件。
2. output
—— 輸出配置
控制打包后的文件名稱和路徑。
作用:指定打包后文件的存儲位置和命名規則。
-
filename
:輸出文件名,可包含占位符(如[name]
,[contenthash]
) -
path
:輸出目錄,必須是絕對路徑
output: {
filename: 'bundle.js', // 輸出的文件名
path: path.resolve(__dirname, 'dist') // 絕對路徑
}
動態命名(用于多入口):filename: '[name].[contenthash].js'
3. mode
:模式設置
mode: 'development' // 或 'production'
作用:指定打包模式,Webpack 會自動啟用對應的優化。
-
development
:-
開啟調試(source map)
-
不壓縮代碼
-
提高構建速度
-
-
production
:-
自動壓縮 JavaScript/CSS
-
啟用 Tree Shaking(移除未使用代碼)
-
更小體積、適合上線
-
4. module
:模塊規則
module: {
rules: [...]
}
作用:定義對不同模塊(如 CSS、JS、圖片等)的處理規則,核心由 rules
數組組成。
每條規則格式如下:
{
test: /\.css$/, // 正則匹配需要處理的文件類型
use: ['style-loader', 'css-loader'] // 使用的 loader(從右到左執行)
}
?? 常見 Loader:
文件類型 | Loader 示例 |
---|---|
JS | babel-loader |
CSS | css-loader 、style-loader |
圖片 | file-loader 、url-loader |
字體 | file-loader |
Vue | vue-loader |
5. plugins
:插件機制
plugins: [new HtmlWebpackPlugin({template: './src/index.html'})
]
作用:擴展 Webpack 的功能,用于執行更復雜的構建任務。
?? 常用插件及作用:
插件名 | 作用 |
---|---|
HtmlWebpackPlugin | 自動生成 HTML 文件并注入打包資源 |
CleanWebpackPlugin | 構建前自動清空輸出目錄 |
MiniCssExtractPlugin | 提取 CSS 到單獨文件 |
DefinePlugin | 定義環境變量 |
6. resolve
:模塊解析配置(可選)
resolve: {extensions: ['.js', '.jsx', '.json']
}
作用:指定在導入模塊時可省略的文件擴展名,提高模塊查找效率。
?? 例如:import App from './App'
// 實際查找:./App.js -> ./App.jsx -> ./App.json
7. devServer
:開發服務器(可選)
devServer: {static: './dist',port: 3000,hot: true
}
作用:啟動本地開發服務器,支持熱更新(HMR),提升開發效率。
HMR(Hot Module Replacement)是 Webpack 在開發環境下的一種“熱更新”功能,允許你在不刷新頁面的情況下替換、更新模塊的內容。
配置說明:
-
static
: 提供靜態文件目錄 -
port
: 設置訪問端口 -
hot
: 啟用熱更新功能(無需刷新頁面即可應用更改)
8. devtool
:調試工具(可選)
devtool: 'source-map'
作用:生成 source map,幫助調試代碼時映射到源碼位置。
常用選項:
-
source-map
:完整 source map,最詳細(用于生產) -
eval-source-map
:快且可調試(用于開發) -
none
:關閉 source map
9. target
:目標平臺(可選)
作用:指定構建目標環境(瀏覽器 / Node.js)
target: 'web' // 或 'node'
二、構建流程
1. 初始化(Initialization)
-
讀取配置文件(
webpack.config.js
) -
初始化 Compiler(核心對象)
-
注冊所有 plugin,進入生命周期鉤子(基于 Tapable)
在 Webpack 中,存在兩個非常重要的核心對象:compiler
、compilation
,它們的作用如下:
- Compiler:Webpack 的核心,貫穿于整個構建周期。
Compiler
封裝了 Webpack 環境的全局配置,包括但不限于配置信息、輸出路徑等。 - Compilation:表示單次的構建過程及其產出。與
Compiler
不同,Compilation
對象在每次構建中都是新創建的,描述了構建的具體過程,包括模塊資源、編譯后的產出資源、文件的變化,以及依賴關系的狀態。在watch mode 下,每當文件變化觸發重新構建時,都會生成一個新的Compilation
實例。
Compiler
是一個長期存在的環境描述,貫穿整個 Webpack 運行周期;而 Compilation
是對單次構建的具體描述,每一次構建過程都可能有所不同。
1. 讀取配置文件
Webpack 啟動時會查找配置文件(默認是 webpack.config.js
),并加載它。
支持的文件格式包括:
-
JavaScript (
webpack.config.js
) -
TypeScript (
webpack.config.ts
) -
JSON(部分字段)
Webpack 會執行配置文件的內容,讀取其中的:
-
entry
,output
-
module.rules
-
plugins
-
mode
,devtool
,resolve
, 等等
?? 注意:Webpack 本質上會執行 require('./webpack.config.js')
,所以你甚至可以在里面寫 JS 邏輯(例如根據環境動態返回不同配置)。
2. 初始化 Compiler 對象
Webpack 內部會構造出一個核心對象: Compiler:const compiler = new Compiler(options);
這個對象是整個構建系統的“大腦”,包含:
-
所有用戶配置
-
所有構建狀態
-
所有鉤子(事件系統)
-
所有模塊、chunk、asset 的數據結構
?? Compiler
不是隨便一個類,它繼承了 Tapable
類,內置了很多“生命周期鉤子”。
例如:
compiler.hooks.run.tap(...)
compiler.hooks.emit.tap(...)
compiler.hooks.done.tap(...)
3. 注冊所有插件(Plugin 注冊階段)
Webpack 執行 plugins
數組中每一個插件的 .apply()
方法,把插件“掛載”到 compiler
上。
const HtmlWebpackPlugin