目錄
- 1、webpack簡介
- 2、簡單示例
- 3、入口(entry)和輸出(output)
- 4、自動生成html文件
- 5、打包css代碼
- 6、優化(單獨提取css代碼)
- 7、優化(壓縮過程)
- 8、打包less代碼
- 9、打包圖片
- 10、搭建開發環境(webpack-dev-server)
- 11、打包模式
- 12、打包模式的應用
- 13、前端項目中注入環境變量
- 14、開發環境中使用 source map 調試
- 15、 解析別名(alias)
- 16、優化-生產環境下使用CDN
- 17、多頁面打包
- 18、優化-分割公共代碼
- 19、完整的示例代碼
- 20、webpack打包和不打包的區別
- 21、webpack 打包原理和 Babel 的作用
- 22、插件(Plugin) 和 加載器(Loader)區別
以下代碼根據 嗶哩嗶哩黑馬程序員視頻整理
1、webpack簡介
更多內容和配置請查看webpack官網
2、簡單示例
3、入口(entry)和輸出(output)
-
新建配置文件:在項目根目錄創建
webpack.config.js
文件,用于配置 Webpack 打包行為。 -
配置入口(
entry
):- 確定入口文件路徑,使用
path.resolve
方法獲取絕對路徑,避免路徑錯誤。 - 示例:
// 引入 Node.js 內置的 path 模塊,用于處理文件路徑,確保路徑解析的正確性 const path = require('path'); module.exports = { // __dirname 表示當前文件(webpack.config.js)所在的目錄路徑,entry: path.resolve(__dirname, 'src/login/index.js'), // 入口文件路徑 };
- 確定入口文件路徑,使用
-
配置出口(
output
):path
:指定打包輸出目錄的絕對路徑。filename
:定義輸出文件的名稱及路徑(相對于path
)。- 示例:
module.exports = { //... output: { path: path.resolve(__dirname, 'dist'), // 輸出目錄 filename: './login/index.js' // 輸出文件名及路徑 } };
-
重新打包:執行打包命令(如
webpack
或自定義腳本),觀察輸出結果。只有與入口文件有直接或間接引入關系的模塊才會被打包。
通過以上配置,可精準控制 Webpack 的打包入口和出口,確保項目資源按預期輸出,提升構建效率與文件管理的規范性。
4、自動生成html文件
使用 html - webpack - plugin
自動生成 html
文件的步驟及配置示例,解析如下:
- 下載插件:
- 命令
npm i html - webpack - plugin --save - dev
,用于在項目中安裝html - webpack - plugin
作為開發依賴,以便在 Webpack 打包時使用該插件生成html
文件。
- 命令
- 配置
webpack.config.js
:- 引入插件:
const HtmlWebpackPlugin = require('html - webpack - plugin')
。 - 在
module.exports
的plugins
數組中添加插件實例,通過template
指定模板文件(如./public/login.html
),通過filename
指定輸出文件路徑及名稱(如./login/index.html
),使 Webpack 具備利用該插件處理html
文件的能力。
- 引入插件:
- 重新打包觀察效果:
- 執行打包命令(如
webpack
),插件會根據配置,基于模板文件生成指定的html
輸出文件,自動引入打包后的資源(如js
文件),無需手動創建或維護html
文件。
- 執行打包命令(如
這些步驟實現了在 Webpack 構建過程中自動生成 html
文件,簡化項目開發流程。
// 引入 html - webpack - plugin 插件,該插件用于在 Webpack 打包過程中自動生成 HTML 文件
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {// 其他配置(如 entry、output 等)可能在此處省略plugins: [// 創建 HtmlWebpackPlugin 的實例,配置生成 HTML 的相關選項new HtmlWebpackPlugin({// 指定模板文件的路徑template: './public/login.html', // 指定生成的 HTML 輸出文件的路徑和名稱// 該路徑是相對于 Webpack 配置中 output.path 的目錄filename: './login/index.html' })]
};
5、打包css代碼
以下是對打包 CSS 代碼相關內容的解析:
1. 加載器作用
- css - loader:主要負責解析 CSS 代碼,例如處理
@import
和url()
等語句,將 CSS 文件轉換為 JavaScript 模塊,使其能被 Webpack 理解和處理。 - style - loader:把
css-loader
解析后的 CSS 代碼以<style>
標簽的形式插入到 HTML 的 DOM 中,從而讓樣式生效。
2. 操作步驟解析
- 步驟1:準備 CSS 文件代碼并引入到
src/login/index.js
中(可能還會進行壓縮轉譯等處理)。這一步是為后續的打包做準備,確保 CSS 代碼能被項目所使用。 - 步驟2:使用
npm i css-loader style-loader --save -dev
下載css-loader
和style-loader
本地軟件包。--save -dev
表示將其保存為開發依賴,因為這些加載器僅在開發和構建過程中使用,而不是在生產環境運行時使用。 - 步驟3:在
webpack.config.js
中進行配置,讓 Webpack 擁有加載 CSS 的功能。以下是配置代碼的詳細注釋:
module.exports = {//... 其他配置(如 entry、output 等,此處省略未展示部分)module: {rules: [{// test 字段用于匹配文件,這里 /\.css$/i 表示匹配所有以.css 結尾的文件,i 表示不區分大小寫test: /\.css$/i, // use 字段指定使用的加載器,加載器的執行順序是從右到左(從后往前)// 先使用 css-loader 解析 CSS 代碼,再使用 style-loader 將解析后的代碼插入到 DOM 中use: ["style-loader", "css-loader"], },],},
};
- 步驟4:執行打包命令后,觀察打包效果,確保 CSS 樣式在最終的頁面中正確呈現。
3. 注意事項
Webpack 默認只識別 JavaScript 代碼,所以對于 CSS 等其他類型的文件,需要通過相應的加載器來處理,使其能夠被正確打包和使用。
6、優化(單獨提取css代碼)
插件作用
mini-css-extract-plugin
插件主要用于將 CSS 代碼從 JavaScript 模塊中提取出來,生成單獨的 CSS 文件。這樣做的好處是 CSS 文件可以被瀏覽器緩存,減少 JavaScript 文件的體積,提高頁面加載性能。
操作步驟解析
- 下載軟件包:使用
npm install --save -dev mini-css-extract-plugin
命令將該插件作為開發依賴安裝到項目中。--save -dev
表示此插件僅在開發和構建過程中使用,而非生產環境。 - 配置
webpack.config.js
:- 首先引入插件:
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
,通過require
函數引入插件模塊,并將其賦值給MiniCssExtractPlugin
變量。 - 然后在
module.rules
中配置 CSS 處理規則:
- 首先引入插件:
module.exports = {//... 其他配置(如 entry、output 等,此處省略未展示部分)module: {rules: [{test: /\.css$/i,// 之前使用 style - loader 和 css - loader,現在用 MiniCssExtractPlugin.loader 替代 style - loaderuse: [MiniCssExtractPlugin.loader, "css-loader"], },],},plugins: [// 實例化插件,啟動插件功能new MiniCssExtractPlugin() ]
};
這里 test: /\.css$/i
用于匹配所有以 .css
結尾的文件,use
數組指定了處理 CSS 文件的加載器。MiniCssExtractPlugin.loader
會將 CSS 提取到單獨文件,css-loader
負責解析 CSS 代碼。同時,在 plugins
數組中實例化 MiniCssExtractPlugin
來啟用插件功能。
3. 觀察打包效果:重新執行 Webpack 打包命令,查看生成的文件中是否有單獨的 CSS 文件,并且頁面樣式是否正常顯示。
注意事項
mini-css-extract-plugin
不能和 style-loader
一起使用。因為 style-loader
是將 CSS 代碼插入到 DOM 中,而該插件是將 CSS 提取成單獨文件,二者功能沖突。
7、優化(壓縮過程)
問題背景
在使用 mini-css-extract-plugin
等插件將 CSS 代碼提取成單獨文件后,CSS 代碼未經過壓縮處理,文件體積較大,影響頁面加載性能,因此需要對其進行壓縮。
插件作用
css-minimizer-webpack-plugin
插件專門用于在 Webpack 構建過程中壓縮 CSS 代碼,通過去除不必要的空格、注釋、簡化選擇器和屬性等方式,減小 CSS 文件的大小,從而加快頁面的加載速度。
操作步驟解析
- 下載軟件包:使用命令
npm install css-minimizer-webpack-plugin --save -dev
將該插件作為開發依賴安裝到項目中。--save -dev
表明此插件僅在開發和構建階段使用,而非在生產環境運行時使用。 - 配置
webpack.config.js
:- 首先引入插件:
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
,通過require
函數引入插件模塊,并將其賦值給CssMinimizerPlugin
變量。 - 然后在
optimization.minimizer
數組中配置插件:
- 首先引入插件:
module.exports = {//... 其他配置(如 entry、output 等,此處省略未展示部分)optimization: {minimizer: [// 在 webpack@5 中,可以使用 `...` 語法來擴展現有的 minimizer(如 `terser-webpack-plugin`),// 確保 JS 代碼也能被壓縮處理(圖中注釋部分說明了這一點,若要啟用可取消注釋相關內容)new CssMinimizerPlugin(),],},
};
這里 optimization.minimizer
用于配置 Webpack 構建過程中的壓縮器。將 CssMinimizerPlugin
的實例添加到 minimizer
數組中,即可在打包時對 CSS 代碼進行壓縮。
3. 觀察打包效果:重新執行 Webpack 打包命令,查看生成的 CSS 文件大小是否減小,同時確認頁面樣式在壓縮后是否正常顯示。
8、打包less代碼
加載器作用
less-loader
加載器的主要作用是將 Less 代碼編譯為 CSS 代碼。Less 是一種 CSS 預處理器,它擴展了 CSS 的語法,增加了變量、Mixin、函數等功能,使得樣式表的編寫更加高效和易于維護。less-loader
能將這些擴展語法轉換為瀏覽器可以識別的 CSS 代碼。
操作步驟解析
- 準備 Less 代碼:新建 Less 代碼文件(例如設置背景圖相關樣式),并將其引入到
src/login/index.js
中。這一步是為了讓 Webpack 能夠找到并處理 Less 代碼。 - 下載軟件包:使用命令
npm i less less-loader --save -dev
下載less
和less-loader
本地軟件包。less
是 Less 語言的核心庫,less-loader
是 Webpack 用于處理 Less 的加載器,--save -dev
表示將它們作為開發依賴安裝,即僅在開發和構建過程中使用。 - 配置
webpack.config.js
:
module.exports = {//... 其他配置(如 entry、output 等,此處省略未展示部分)module: {rules: [{test: /\.less$/i,// use 數組指定了處理 Less 文件的加載器,執行順序從右到左(從后往前)// less - loader 先將 Less 代碼編譯為 CSS 代碼,css - loader 解析 CSS 代碼,// MiniCssExtractPlugin.loader 將 CSS 提取到單獨文件(前提是已配置該插件用于提取 CSS)use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"] },],},
};
這里 test: /\.less$/i
用于匹配所有以 .less
結尾的文件,use
數組按照順序依次使用不同的加載器對 Less 文件進行處理。
4. 觀察打包效果:重新執行 Webpack 打包命令,查看打包后的結果,確認 Less 代碼是否成功編譯為 CSS 代碼,并且頁面樣式是否正常顯示。
注意事項
less-loader
需要配合 less
軟件包使用,二者缺一不可。如果只安裝了 less-loader
而沒有安裝 less
,在編譯 Less 代碼時會報錯。
9、打包圖片
- 資源模塊:Webpack5 內置資源模塊,可直接打包字體、圖片等,無需額外 loader。
- 配置步驟:在
webpack.config.js
中配置規則,如通過test: /\.(png|jpg|jpeg|gif)$/i
匹配圖片文件,type: 'asset'
啟用資源模塊,generator.filename
定義輸出文件名(利用[hash]
對內容哈希計算,[ext]
保留原文件擴展名,[query]
保留查詢參數)。 - 臨界值判斷:默認以 8KB 為臨界值。大于 8KB 的圖片會打包為單獨文件并導出 URL 地址;小于 8KB 的圖片則導出為
data URI
(base64 字符串),減少 HTTP 請求。
10、搭建開發環境(webpack-dev-server)
- 問題:修改代碼后需重新打包才能查看運行效果,效率低。
- 開發環境配置:
- 作用:啟動 Web 服務,自動檢測代碼變化并熱更新到網頁,且
dist
目錄和打包內容在內存中,更新速度快。 - 步驟:
- 下載
webpack-dev-server
軟件包到項目,命令為npm i webpack-dev-server --save -dev
。 - 設置模式為開發模式(
mode: 'development'
),并在package.json
中配置自定義命令(如"dev": "webpack serve --open"
,--open
可自動打開瀏覽器)。 - 使用
npm run dev
啟動開發服務器,體驗熱更新效果。
- 下載
- 作用:啟動 Web 服務,自動檢測代碼變化并熱更新到網頁,且
11、打包模式
12、打包模式的應用
- 需求:開發模式下用
style-loader
內嵌樣式以加快速度,生產模式下提取 CSS 代碼。 - 方案:
-
方案 1:直接在
webpack.config.js
配置導出函數,但局限性大(僅支持 2 種模式)。
-
方案 2:借助
cross-env
(跨平臺通用)包區分環境:- 下載
cross-env
到項目:npm i cross-env --save -dev
。 - 在
package.json
中配置自定義命令,通過cross-env
設置參數(如NODE_ENV=production
或NODE_ENV=development
),參數會綁定到process.env
對象。 - 在
webpack.config.js
中根據process.env.NODE_ENV
區分環境,應用不同配置。 - 重新打包觀察配置差異。
- 下載
-
方案 3:當多種模式差異性較大時,配置不同的
webpack.config.js
文件。
-
13、前端項目中注入環境變量
- 需求:開發模式下打印語句生效,生產模式下失效。
- 問題:
cross-env
設置的環境變量僅在Node.js
環境生效,前端代碼無法直接訪問process.env.NODE_ENV
。 - 解決方法:使用 Webpack 內置的
DefinePlugin
插件。該插件在編譯時將前端代碼中匹配的變量名替換為對應的值或表達式。 - 代碼實現:
- 引入 Webpack:
const webpack = require('webpack')
。 - 在
webpack.config.js
的plugins
數組中添加DefinePlugin
實例:
這樣,前端代碼就能根據plugins: [new webpack.DefinePlugin({// 鍵為注入到前端 JS 代碼中的全局變量名// 值通過 JSON.stringify 處理(確保值為字符串形式,符合前端代碼規范)'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)}) ]
process.env.NODE_ENV
的值(如'development'
或'production'
)判斷是否執行相應邏輯(如開發模式下的打印語句)。
- 引入 Webpack:
14、開發環境中使用 source map 調試
- 問題:代碼壓縮混淆后,無法準確定位源代碼的行數和列數。
source map
的作用:能準確追蹤error
和warning
在原始代碼中的位置。- 設置方式:在
webpack.config.js
中配置devtool
選項,例如devtool: 'inline - source - map'
,該選項會將源碼的位置信息一同打包在js
文件內。 - 注意事項:
source map
僅適用于開發環境,生產環境中不建議使用,以防止源碼位置被輕易查看。
15、 解析別名(alias)
- 作用:配置模塊解析規則,通過創建
import
引入路徑的別名,簡化模塊引入,避免長路徑或相對路徑的不安全性。 - 實現方式:在
webpack.config.js
中配置resolve.alias
。例如,使用path.resolve(__dirname, 'src')
將別名@
指向項目的src
絕對路徑。- 原引入方式:
import { checkPhone, checkCode } from '../src/utils/check.js'
(路徑長且相對路徑不夠安全)。 - 配置別名后:
import { checkPhone, checkCode } from '@/utils/check.js'
(通過別名@
簡化路徑)。
- 原引入方式:
- 代碼示例:
const config = {//...其他配置resolve: {alias: {'@': path.resolve(__dirname,'src') // 將 @ 映射到 src 目錄的絕對路徑}} }
通過這種配置,可使模塊引入更簡潔、安全,提升開發效率。
16、優化-生產環境下使用CDN
具體示例
-
使用模塊語法判斷
-
配置忽略的模塊
-
使用參數
17、多頁面打包
具體示例
18、優化-分割公共代碼
Webpack 會自動分析模塊依賴關系,將符合規則的公共代碼提取到獨立文件,減少重復代碼,提升緩存利用率和打包效率。
19、完整的示例代碼
webpack.config.js文件
const path = require('path'); // 用于處理文件路徑的Node.js核心模塊
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 生成HTML文件并自動引入打包后的JS/CSS資源
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 生產環境中將CSS提取為獨立文件(替代style-loader)
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); // 優化壓縮CSS代碼(配合terser-webpack-plugin)
const webpack = require('webpack'); // 引入Webpack核心模塊,用于使用內置插件(如DefinePlugin)const config = {// 打包模式(development/production,通過命令行參數覆蓋配置文件)// mode: 'development', // 開發模式默認開啟調試相關配置(如eval-source-map)// 多入口配置(每個頁面單獨打包)entry: {// 鍵名對應最終生成的chunk名稱,值為入口文件絕對路徑'login': path.resolve(__dirname, 'src/login/index.js'), // 登錄頁面入口'content': path.resolve(__dirname, 'src/content/index.js'), // 內容頁面入口'publish': path.resolve(__dirname, 'src/publish/index.js') // 發布頁面入口},// 輸出配置output: {path: path.resolve(__dirname, 'dist'), // 打包輸出的根目錄(絕對路徑)filename: './[name]/index.js', // 輸出文件名模板:[name]對應entry的鍵名(如login/index.js)clean: true // 打包前自動清空output.path目錄(避免殘留舊文件)},// 插件配置(增強Webpack功能)plugins: [// 登錄頁HTML模板處理new HtmlWebpackPlugin({template: path.resolve(__dirname, 'public/login.html'), // 源HTML模板文件路徑filename: path.resolve(__dirname, 'dist/login/index.html'), // 生成的HTML文件路徑useCdn: process.env.NODE_ENV === 'production', // 生產環境啟用CDN資源(通過模板變量控制)chunks: ['login'] // 僅引入當前entry對應的chunk(避免引入其他頁面的JS)}),// 內容頁HTML模板處理(結構同上)new HtmlWebpackPlugin({template: path.resolve(__dirname, 'public/content.html'),filename: path.resolve(__dirname, 'dist/content/index.html'),useCdn: process.env.NODE_ENV === 'production',chunks: ['content']}),// 發布頁HTML模板處理(結構同上)new HtmlWebpackPlugin({template: path.resolve(__dirname, 'public/publish.html'),filename: path.resolve(__dirname, 'dist/publish/index.html'),useCdn: process.env.NODE_ENV === 'production',chunks: ['publish']}),// CSS提取插件(生產環境生效)new MiniCssExtractPlugin({filename: './[name]/index.css' // 生成的CSS文件名(與JS文件路徑對應)}),// 環境變量注入插件(將Node環境變量傳遞到前端代碼)new webpack.DefinePlugin({// 使用JSON.stringify確保值為字符串形式(符合JS語法)'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)})],// 模塊加載器配置(處理非JS文件)module: {rules: [// CSS文件處理規則{test: /\.css$/i, // 匹配所有.css文件(i表示不區分大小寫)// 根據環境選擇不同的加載器:開發環境用style-loader(內聯樣式),生產環境用MiniCssExtractPlugin.loader(提取文件)use: [process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, "css-loader"]},// Less文件處理規則(支持CSS預處理器){test: /\.less$/i, // 匹配所有.less文件use: [// 同上:環境區分CSS加載方式process.env.NODE_ENV === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader,'css-loader', // 解析CSS文件中的@import和url()'less-loader' // 將Less代碼編譯為CSS],},// 圖片文件處理規則(Webpack5內置資源模塊){test: /\.(png|jpg|jpeg|gif)$/i, // 匹配常見圖片格式type: 'asset', // 自動根據文件大小選擇處理方式(<8KB轉base64,否則生成獨立文件)generator: {filename: 'assets/[hash][ext][query]' // 輸出文件名:哈希值+原擴展名+查詢參數}}],},// 優化配置(生產環境關鍵優化)optimization: {// 壓縮器配置(支持JS/CSS壓縮)minimizer: [// 保留默認JS壓縮器(terser-webpack-plugin,Webpack5內置)// `...` 展開運算符表示保留原有minimizer配置`...`,new CssMinimizerPlugin(), // 單獨配置CSS壓縮器(配合默認JS壓縮器工作)],// 代碼分割配置(核心優化點)splitChunks: {chunks: 'all', // 對所有模塊(同步/異步/初始加載)進行公共代碼分析cacheGroups: { // 緩存組(自定義分割規則)commons: { // 公共模塊分組(抽取多個頁面共享的代碼)minSize: 0, // 允許分割任意大小的模塊(覆蓋默認30KB限制)minChunks: 2, // 模塊被引用至少2次才進行分割reuseExistingChunk: true, // 重用已存在的chunk(避免重復生成)// 動態生成chunk名稱:基于引用該模塊的所有chunk名稱拼接name(module, chunks, cacheGroupKey) { const allChunksNames = chunks.map((item) => item.name).join('~'); // 格式:chunk名1~chunk名2return `./js/${allChunksNames}`; // 輸出路徑:dist/js/[chunk名1~chunk名2].js}}}}},// 模塊解析配置(簡化路徑引用)resolve: {// 路徑別名配置(避免使用復雜相對路徑)alias: {'@': path.resolve(__dirname, 'src') // 用@符號代替src目錄絕對路徑(如import '@/utils/xxx')}}
};// 開發環境配置(僅在NODE_ENV=development時生效)
if (process.env.NODE_ENV === 'development') {config.devtool = 'inline-source-map'; // 啟用內聯source map(方便調試,顯示原始代碼位置)
}// 生產環境配置(僅在NODE_ENV=production時生效)
if (process.env.NODE_ENV === 'production') {// 外部擴展配置(排除指定庫的打包,通過CDN引入)config.externals = {// 鍵:import語句中的模塊名,值:全局變量名(需與CDN暴露的變量一致)'bootstrap/dist/css/bootstrap.min.css': 'bootstrap', // 引導CSS(假設全局變量為bootstrap)'axios': 'axios', // axios庫(全局變量axios)'form-serialize': 'serialize', // form-serialize庫(全局變量serialize)'@wangeditor/editor': 'wangEditor' // 王編輯器(全局變量wangEditor)}
}module.exports = config; // 導出完整配置對象
代碼說明:
- 多入口配置:針對不同頁面(登錄/內容/發布)設置獨立入口,生成對應的HTML和JS/CSS文件
- 環境區分:通過
process.env.NODE_ENV
動態切換開發/生產環境配置(如CSS加載方式、source map、外部擴展) - 公共代碼分割:通過
splitChunks.commons
規則,自動提取被多個頁面引用的公共模塊(如工具函數、公共組件) - 資源處理:
- CSS/Less:開發環境內聯樣式提升速度,生產環境提取獨立文件并壓縮
- 圖片:使用Webpack5內置
asset
模塊自動處理base64嵌入和獨立文件生成
- 性能優化:
clean: true
確保輸出目錄無殘留文件externals
排除第三方庫打包,減少最終包體積(配合CDN使用)splitChunks
提升緩存利用率(公共代碼變更時僅需重新打包該部分)
使用建議:
- 開發環境通過
npm run dev
啟動(需配置webpack-dev-server
) - 生產環境通過
NODE_ENV=production npm run build
打包(需確保CDN資源已正確引入) - 可根據實際需求調整
splitChunks.minChunks
(公共模塊引用次數閾值)和minSize
(文件大小閾值)
package.json文件
{"name": "","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "cross-env NODE_ENV=production webpack --mode=production","dev": "cross-env NODE_ENV=development webpack serve --open --mode=development"},"keywords": [],"author": "","license": "ISC","devDependencies": {"cross-env": "^7.0.3","css-loader": "^6.7.3","css-minimizer-webpack-plugin": "^5.0.0","html-webpack-plugin": "^5.5.1","less": "^4.1.3","less-loader": "^11.1.0","mini-css-extract-plugin": "^2.7.5","style-loader": "^3.3.2","webpack": "^5.82.0","webpack-cli": "^5.1.1","webpack-dev-server": "^4.15.0"},"dependencies": {"@wangeditor/editor": "^5.1.23","axios": "^1.4.0","bootstrap": "^5.2.3","form-serialize": "^0.7.2"}
}
20、webpack打包和不打包的區別
- 運行效率:
- 不打包時,瀏覽器需逐個請求眾多模塊文件,HTTP 請求次數多,加載速度慢。尤其在現代項目模塊繁雜的情況下,效率低下。
- Webpack 打包將多個模塊合并為少量文件,減少 HTTP 請求次數。同時,打包過程可壓縮代碼(如去除冗余字符、優化代碼結構),減小文件體積,顯著提升瀏覽器加載與運行效率。
- 對基礎的支持:
- 不打包時,瀏覽器可能無法識別現代前端的新特性(如 ES6+ 的
import/export
模塊語法)及預處理文件(如less
、scss
),導致無法正確解析運行。 - Webpack 可通過
loader
對代碼進行轉換處理,例如:用babel - loader
將 ES6+ 代碼轉譯為兼容舊瀏覽器的代碼;用css - loader
、less - loader
處理樣式文件;用資源模塊處理圖片、字體等。通過這些方式,確保項目在不同環境中正常運行,增強對各類基礎的支持。
- 不打包時,瀏覽器可能無法識別現代前端的新特性(如 ES6+ 的
總結區別:
- 運行效率:Webpack 打包減少 HTTP 請求、壓縮文件,提升加載與運行速度;不打包則因請求多、文件未優化,效率低。
- 對基礎的支持:Webpack 打包通過
loader
轉換代碼與資源,支持現代前端特性與復雜資源;不打包時,瀏覽器對新特性和特殊資源支持不足,可能導致項目無法正常運行。
21、webpack 打包原理和 Babel 的作用
webpack 打包原理:
Webpack 將 JavaScript、CSS、圖像等都視為模塊,通過 import
/require
語句建立模塊間的依賴關系。從入口文件出發,遞歸解析依賴的所有模塊,將它們打包成少量文件(如 bundle.js
)。打包過程中:
- 支持代碼分割,把
bundle
拆分為多個小文件,實現異步按需加載,提升性能。 - 若某模塊被多個文件引用,僅生成一個文件,避免重復。
- 未被調用的文件、變量和方法不會被打包,減少冗余。
- 多入口場景下,若不同入口引入相同代碼,可借助插件(如
SplitChunksPlugin
)抽離到公共文件,優化重復代碼。
Babel 的作用:
Babel 是一個 JavaScript 編譯器,核心功能是將現代 JavaScript 代碼(如 ES6+ 的 let
、const
、箭頭函數、對象展開運算符等)轉換為舊瀏覽器或環境能理解的 ES5 等兼容語法,解決新語法的兼容性問題。通過配置插件和預設(如 @babel/preset - env
),還能支持對 JSX(用于 React)、裝飾器等特殊語法的轉換,確保代碼在不同環境中穩定運行。
22、插件(Plugin) 和 加載器(Loader)區別
一、核心定義與功能
- 加載器(Loader)
-
定義:
加載器是用于 處理特定類型文件 的轉換器,將瀏覽器無法直接識別的模塊(如 CSS、Less、圖片、字體等)轉換為 Webpack 能夠處理的模塊
。 -
核心功能:
- 文件轉換:將非 JS 文件轉換為 JS 可識別的模塊(或直接轉換為最終可執行的代碼/資源)。
- 單模塊處理:僅針對單個模塊的內容進行處理(如將
.vue
文件拆分為 JS/CSS/HTML,將 Less 編譯為 CSS)。
-
典型場景:
babel-loader
:將 ES6+ 語法轉換為 ES5 兼容代碼。css-loader
:解析 CSS 文件中的@import
和url()
依賴。image-loader
:壓縮圖片并生成 URL 路徑。
- 插件(Plugin)
-
定義:
插件是用于 擴展 Webpack 構建流程 的功能模塊,通過監聽 Webpack 的生命周期鉤子(如編譯開始
、文件生成后
等),在構建過程中執行自定義邏輯。 -
核心功能:
- 全局構建控制:處理構建過程中的全局邏輯(如生成 HTML、提取 CSS、代碼壓縮、環境變量注入等)。
- 多模塊協作:操作多個模塊之間的關系(如代碼分割、資源優化、錯誤處理等)。
-
典型場景:
HtmlWebpackPlugin
:根據模板生成 HTML 文件并自動引入打包后的 JS/CSS。MiniCssExtractPlugin
:將 CSS 從 JS 中提取為獨立文件(生產環境常用)。TerserPlugin
:壓縮 JS 代碼(Webpack 5 內置)。
二、核心區別對比
特性 | 加載器(Loader) | 插件(Plugin) |
---|---|---|
作用對象 | 單個模塊文件(如 .js 、.css 、.vue ) | 整個構建流程(處理模塊間關系或全局任務) |
處理階段 | 模塊加載時(在 module.rules 中配置) | 構建生命周期的各個鉤子階段(通過 plugins 數組配置) |
核心目標 | 文件轉換(讓 Webpack 識別非 JS 模塊) | 擴展構建功能(優化、壓縮、資源管理等全局操作) |
使用方式 | 在 module.rules 中通過 test 匹配文件類型,按順序調用 use 中的加載器 | 在 plugins 中實例化插件類(可傳入配置參數) |
典型配置位置 | webpack.config.js 中的 module.rules 字段 | webpack.config.js 中的 plugins 數組 |
輸出結果 | 轉換后的模塊內容(供 Webpack 繼續處理) | 無直接輸出,影響構建流程或生成額外資源(如 HTML) |
三、協作關系
-
加載器是模塊處理的“轉換器”:
當 Webpack 解析到一個模塊(如import './style.css'
),會根據module.rules
匹配對應的加載器,按順序調用(如先css-loader
解析依賴,再style-loader
內聯樣式到 HTML)。 -
插件是構建流程的“控制器”:
插件在加載器處理完模塊后介入,例如:MiniCssExtractPlugin
會將css-loader
處理后的 CSS 從 JS 中提取為獨立文件(替代style-loader
的內聯方式)。HtmlWebpackPlugin
會根據所有打包后的 JS/CSS 生成最終的 HTML 模板。
四、示例對比
- 加載器示例:處理 CSS 文件
// webpack.config.js
module.rules = [{test: /\.css$/, // 匹配 CSS 文件use: ['style-loader', // 將 CSS 內聯到 HTML 樣式標簽(開發環境)'css-loader' // 解析 CSS 中的 @import 和 url()]}
];
- 插件示例:提取 CSS 為獨立文件
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');plugins: [new MiniCssExtractPlugin({filename: 'css/[name].[contenthash].css' // 生產環境生成獨立 CSS 文件})
];// 配合加載器使用(替換 style-loader)
use: [MiniCssExtractPlugin.loader, // 插件提供的加載器,用于提取 CSS'css-loader'
]
五、總結
- 加載器(Loader):專注于 單個文件的內容轉換,是模塊級的“翻譯官”(如將 Less 轉 CSS,ES6 轉 ES5)。
- 插件(Plugin):專注于 構建流程的全局控制,是構建過程的“指揮官”(如生成 HTML、分離公共代碼、壓縮資源)。
兩者相輔相成:Loader 處理基礎文件轉換,Plugin 實現高級構建功能,共同完成復雜的前端工程化需求。