本文分享自華為云社區《webpack5快速入門,船新版本,建議收藏》,作者:北極光之夜。。
一. 快速上手
1.1 Webpack功能:
打包: 將不同類型資源按模塊處理進行打包。
靜態: 打包后最終產出靜態資源。
模塊: webpack 支持不同規范的模塊化開發。
1.2 安裝webpack:
終端輸入: npm install webpack -g
1.3 快速模擬搭建一個項目目錄:

utiles.js:
function add(a,b){ console.log(a+b); } export {add} ;
index.js:
import {add} from './utiles/utiles.js' add(6,9);
1.4 webpack打包:
終端輸入:webpack
webpack會自動尋找src目錄,然后尋找index.js入口文件,然后進行打包,最終生成一個dist目錄為打包后內容。

index.html引入:
<script src="../dist/main.js"></script>
結果:

二.基本使用:
2.1.配置文件:
可以在配置文件里定義配置,表示你想如何打包,能設置很多條件。webpack會根據你配置文件的配置規則來進行打包。在src同級目錄下新建一個webpack.config.js文件,里面寫配置信息。
如最基本的入口和出口:
const path = require('path'); module.exports = { //打包入口文件路徑 entry: './src/index.js', //path打包出口路徑,filename寫打包后文件名 output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', }, };
終端輸入webpack后成功打包了build.js文件,跟上面打包的main.js內容一樣:

2.2.loader:
為什么使用loader:
webpack 只能理解 JavaScript 和 JSON 文件,這是 webpack 開箱可用的自帶能力。loader 能讓 webpack 能夠去處理其他類型的文件(比如css類型文件,圖片類型,txt類型等等),并將它們轉換為有效模塊,以供使用。
2.2.1 css-loader:
比如,我想webpack能打包css,終端輸入以下命令先安裝css-loader:
npm i css-loader -D
1.可以在導入css文件的時候指定loader,這樣就不報錯了,在導入css文件路徑前添加css-loader!:
import 'css-loader!./css/index.css'
2.當然,也可以在配置文件設置:
const path = require('path'); module.exports = { //打包入口文件路徑 entry: './src/index.js', //path打包出口路徑,filename打包后文件名 output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', }, //定義一些規則 module: { //數組里每個元素為一個規則 rules:[ { test: /\.css$/, use: [ {loader: 'css-loader'} ] //簡寫為 use: ['css-loader'] } ] } };
test 屬性,定義一個正則表達式,匹配需要處理的文件類型。識別出哪些文件會被轉換。
use 屬性,定義出在進行轉換時,應該使用哪個 loader。
配置文件里配置后,別忘了在index入口文件導入css文件。
2.2.2 style-loader:
上面css-loader只是能識別css文件,而引入了style-loader后css樣式才能在頁面展示。
安裝:
npm i style-loader -D
配置文件規則:
因為 webpack 是 從 后 往 前 執 行 ,所以style-loader寫在css-loader前面。
module: { //數組里每個元素為一個規則 rules:[ { test: /\.css$/, use: ['style-loader','css-loader'] } ] }
2.2.3 sass-loader:
比如,我想 webpack 能打包scss文件類型。不會sass的可以看這篇文章文章sass全解析。
安裝sass:
npm i sass -D
轉換scss為css(注意在scss同級路徑下轉換,也是終端輸入):
sass index.scss:ouput.css
在入口文件index.js導入:
import './css/ouput.css'
安裝sass-loader:
npm i sass-loader -D
配置規則:
//定義一些規則 module: { //數組里每個元素為一個規則 rules:[ { test: /\.css$/, use: ['style-loader','css-loader'] }, { test: /\.scss$/, use: ['style-loader','css-loader'] } ] }
打包:
webpack
2.3 browserslist:
Webpack 支持所有符合 ES5 標準 的瀏覽器(不支持 IE8 及以下版本)。如果你想要支持舊版本瀏覽器,那就需要借助到一些工具了。在安裝webpack時默認安裝了browserslist,它可以知道各個瀏覽器的占有率數據并配置。
這個網站也可以查到目前各個瀏覽器的占有率數據。后面再詳細講。
2.4 postcss-loader處理css兼容:
postcss是JavaScript轉換樣式的工具,這個工具能處理css兼容問題。就是這個工具能給我們寫的css代碼添加一些兼容的前綴。
首先,你可以通過 這個網站 了解css是添加什么前綴怎么能兼容主流瀏覽器的。

安裝:
npm i postcss-loader -D npm i autoprefixer -D
配置文件:
在css文件類型里添加postcss-loader,并配置參數 :
{ test: /\.css$/, use: [ 'style-loader', 'css-loader', //添加postcss-loader { loader:'postcss-loader', //配置參數 options:{ postcssOptions:{ //添加插件autoprefixer,能加前綴 plugins:[ require('autoprefixer') ] } } } ] },
在index.js同級下新建一個名為.browserslistrc 文件,里面寫兼容的條件,如:
> 0.1% last 2 version not dead
然后終端輸入webpack打包后css代碼會自動添加兼容代碼。
上面只是添加前綴,如果還需要更強的兼容需要 postcss-preset-env, 安裝:
npm i postcss-preset-env -D
添加配置(來次全的):
const path = require('path'); module.exports = { //打包入口文件路徑 entry: './src/index.js', //path打包出口路徑,filename打包后文件名 output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', }, //定義一些規則 module: { //數組里每個元素為一個規則 rules:[ { test: /\.css$/, use: [ 'style-loader', 'css-loader', //添加postcss-loader { loader:'postcss-loader', //配置參數 options:{ postcssOptions:{ //添加插件autoprefixer,能加前綴 plugins:[ require('autoprefixer'), require('postcss-preset-env') ] } } } ] }, { test: /\.scss$/, use: ['style-loader','css-loader'] } ] } };
可以只保留postcss-preset-env,簡寫:
{ test: /\.css$/, use: [ 'style-loader', 'css-loader', //添加postcss-loader { loader:'postcss-loader', //配置參數 options:{ postcssOptions:{ //添加插件autoprefixer,能加前綴 plugins:['postcss-preset-env'] } } } ] },
不過一般是在index.js同級下新建一個postcss.config.js文件專門寫配置:
postcss.config.js文件內容:
module.exports = { plugins: [ require('postcss-preset-env') ] }
然后在webpack.config.js配置文件里直接導入postcss-loader就行:
use: [ 'style-loader', 'css-loader', //添加postcss-loader 'postcss-loader' ]
2.5 importLoaders:
importLoaders:用于配置「css-loader 作用于 @import 的資源之前」有多少個 loader。直白來說就是importLoaders設置幾,那么通過@import 導入的css文件也會向前執行前面不再執行的loader。
如下:
use: [ 'style-loader', { loader:'css-loader', options:{ importLoaders:1 } }, 'postcss-loader' ]
本來一個css文件會執行上面3個loader,如果那個css文件存在通過import語法導入的css文件,那么那個導入的css文件是不會執行最后的postcss-loader。但是我想執行,所以配置importLoaders,表示import導入的css文件也會向后執行多少個loader。(注意webpack是從后往前執行的)
2.6 file-loader處理圖片:
file-loader作用:
1.當我們把圖片當一個模塊導入的時候可以識別它。
2.可以把二進制資源拷貝一份到指定目錄,沒指定就是默認dist目錄。
安裝:
npm i file-loader -D
2.6.1 在js里通過src導入的:
可以在src目錄下新建一個img文件夾存放圖片。
配置文件(在rules數組里繼續新增一個規則):
{ test: /\.(png|svg|gif|jpe?g)$/, use:['file-loader'] }
var img = document.createElement('img'); img.src = require('../img/1.jpg').default; document.body.appendChild(img);
{ test: /\.(png|svg|gif|jpe?g)$/, use:{ loader:'file-loader', options: { esModule:false } } }
先導入圖片模塊:
import src from '../img/1.jpg';
然后再:
var img = document.createElement('img'); img.src = src; document.body.appendChild(img);
最后終端webpack打包就行,目前會將圖片默認打包到dist目錄。
2.6.2 在css里通過url導入的:
跟上面src區別就是要修改的是css類型文件規則,加一個esModule參數:
{ test: /\.css$/, use: [ 'style-loader', { loader:'css-loader', options:{ importLoaders:1, esModule:false } }, 'postcss-loader' ] }, { test: /\.(png|svg|gif|jpe?g)$/, use: ['file-loader'] }
然后在css里通過url正常引用即可,webpack打包后會將圖片默認打包到dist目錄:
div { width: 200px; height: 200px; background-image: url("../img/1.jpg"); }
默認位置,如(圖片名稱自動根據內容算法得出):

2.6.3 設置輸出位置與圖片名稱:
我們可以設置打包后的圖片存放到的地方與名稱。
修改配置文件的圖片規則,添加一個name配置(名稱)屬性和outputpath屬性(位置):
{ test: /\.(png|svg|gif|jpe?g)$/, use: { loader:'file-loader', options:{ name: '[name].[hash:6].[ext]', outputPath: 'img' } } }
其中name屬性里表示:【ext】擴展名,【name】文件名,【hash】文件內容。outputpath屬性:直接指定img目錄,默認會放在dist目錄下。

兩個屬性可以合并直接簡寫為:
{ test: /\.(png|svg|gif|jpe?g)$/, use: { loader:'file-loader', options:{ name: 'img/[name].[hash:6].[ext]', } } }
2.7 url-loader處理圖片:
url-loader可以將圖片轉為base64字符串,能更快的加載圖片(適用圖片文件較少情況,過大的話還是用file-loader)。file-loader相對于拷貝,速度較慢。
安裝:
npm i url-loader -D
配置其實跟file-loader差不多的,把loader那一改就行:
{ test: /\.(png|svg|gif|jpe?g)$/, use: { loader:'url-loader', options:{ name: 'img/[name].[hash:6].[ext]', } } }
與file-loader不同的是,打包后圖片會以base64字符串形式加載到代碼里,所以目錄里不再可見:

關鍵的是,其實 url-loader 包含 file-loader ,可以設置一個 limit 屬性,當圖片大小超過limit,url-loader會自認不行,會主動去調用file-loader去執行。
如下:設置一個筏值20kb,小于它會執行url-loader,大于它會執行file-loader
{ test: /\.(png|svg|gif|jpe?g)$/, use: { loader:'url-loader', options:{ name: 'img/[name].[hash:6].[ext]', limit: 20*1024 } } }
2.8 asset處理圖片:
webpack5之后可以直接使用asset處理圖片,不必再配置file-loader或url-loader。能更好的簡化使用。且它是webpack5內置模塊,不必額外進行安裝其它東西。
配置文件修改圖片規則:
1、默認情況,拷貝圖片,默認放到dist目錄下(跟file-loader沒配置名稱和路徑時結果一樣):
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset/resource' }

2、指定圖片打包后位置,放到dist下的img文件夾里,圖片規則跟上面一樣,要修改的是output打包出口路徑那里,新增assetModuleFilename:
//path打包出口路徑,filename打包后文件名 output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', assetModuleFilename:'img/[name].[hash:6][ext]' }, { test: /\.(png|svg|gif|jpe?g)$/, type: 'asset/resource' }

3、上面相當于全局配置,不論什么圖片都會執行,所以不大好,所以還是在規則里面加圖片輸出位置與名稱好點,新增generator,里面的filename寫位置與名稱:
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset/resource', generator:{ filename:'img/[name].[hash:6][ext]' } }

4、如果想將圖片轉為base64字符串,而不是拷貝的話,修改規則如下:
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset/inline', }
5、當然,也能像url-loader設置limit那樣設置一個閥值,超過后還是用拷貝,修改規則如下,maxSize設置大小,這里閥值為30kb大小:
{ test: /\.(png|svg|gif|jpe?g)$/, type: 'asset', generator:{ filename:'img/[name].[hash:6][ext]' }, parser:{ dataUrlCondition: { maxSize: 30*1024 } } }
2.9 asset處理字體圖標:
新增如下規則:
// 字體圖標 { test: /\.(ttf|woff2?)$/, type:'asset/resource', generator:{ filename:'font/[name].[hash:3][ext]' }, }
2.10 webpack插件使用:
眾所周知,插件能幫助我們更方便的做更多的事情。
2.10.1 dist目錄自動清空插件:
每次我們重新webpack打包的時候還要把上次打包的dist目錄刪除掉,麻煩,所以這里下載一個dist目錄自動清空插件。以后打包會默認把上次打包內容清空后打包。
安裝clean-webpack-plugin插件:
npm i clean-webpack-plugin -D
設置配置文件的配置項plugins:
const path = require('path'); // 1.先導入下載的插件 const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', }, module: {。。。}, //2.定義插件配置的屬性 plugins ,存放每個插件 plugins: [ //3.每個插件都是一個類,直接new就行 new CleanWebpackPlugin() ] };
每個插件都是一個類,直接new就行,可以查看對應插件的官網,了解傳的參數對應什么功能。
2.10.2 html-webpack-plugin插件:
能幫我們打包后在打包目錄里生成一個html文件模板,并引用入口文件。
安裝html-webpack-plugin插件:
npm i html-webpack-plugin -D
設置配置文件的配置項plugins:
const path = require('path'); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); // 1.先導入下載的插件 const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', }, module: {。。。}, plugins: [ new CleanWebpackPlugin(), // 2.添加 new HtmlWebpackPlugin() ] };
webpack打包后:

html默認內容:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Webpack App</title> <meta name="viewport" content="width=device-width,initial-scale=1" /> <script defer="defer" src="build.js"></script> </head> <body></body> </html>
對于html很多地方可以設置的,比如title的內容啥的,在配置文件new的時候傳遞對應參數就行(具體參考該插件官網):
。。。略 plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title:'北極光之夜。' }) ]
打包后生成的html文件內容:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>北極光之夜。</title> <meta name="viewport" content="width=device-width,initial-scale=1" /> <script defer="defer" src="build.js"></script> </head> <body></body> </html>
當然,可以自己提供一個html模板,以我提供的模板為基礎生成新的html模板:
1、在src同級下新建一個public目錄,在里面新建一個index.html文件作為模板:

2、比如index.html內容如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <div id="app">test</div> </body> </html>
<%= htmlWebpackPlugin.options.title %>表示使用配置里的title。
3、新增template參數,值為模板路徑:
new HtmlWebpackPlugin({ title:'北極光之夜。', template:'./public/index.html' })
4、打包結果:

2.11 babel-loader處理js兼容:
能處理js兼容問題,比如兼容es6語法。
安裝:
npm i @babel/core -D npm i babel-loader -D
在index.js同級下新建一個babel.config.js文件專門寫配置:
babel.config.js文件內容:
module.exports = { presets: ['@babel/preset-env'] }
然后在webpack.config.js配置文件里新增規則:
{ test:/\.js$/, use:['babel-loader'] }
跟在前面說到的postcss-loader一樣,同樣在.browserslistrc 文件里面寫兼容的條件,如:
0.1%
last 2 version
not dead
最后webpack打包就行了。
2.12 polyfill處理js兼容:
babel-loader處理的js兼容還不夠多,只能處理簡單的,若存在promise這些新語法也不大行。所以需要polyfill。
安裝:
npm i @babel/polyfill --save
修改babel.config.js:
module.exports = { presets: [ '@babel/preset-env', { useBuiltIns: 'entry', crorejs: 3 } ] }
2.13 自動更新:
可以實現你修改源碼后,打包后的代碼也自動更新,不用每次都手動打包去更新。
1、不使用webpack-dev-serve之前,可以在配置文件添加watch屬性為true也能實現自動更新,但是性能不太好,不能局部更新,是一有更新就全都更新:
如:
module.exports = { // 這里,自動更新 watch: true, //打包入口文件路徑 entry: './src/index.js', //path打包出口路徑,filename打包后文件名 output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', //assetModuleFilename:'img/[name].[hash:6][ext]' }, 。。。略 }
2、webpack-dev-serve性能較好,能實現局部更新,節省性能。
在終端先安裝:
npm install webpack-dev-server --save-dev
以后打包命令改為:
webpack serve
2.14 HMR模塊熱替換:
作用:一個模塊發生變化,只會重新打包這一個模塊(而不是打包所有模塊),極大的提升構建速度。
先配置:
module.exports = { target: 'web', // 開啟HMR devServer:{ hot: true } 。。。 }
然后在入口文件處通過判斷給需要熱更新的模塊熱更新:
import './title' if(module.hot){ module.not.accept(['./title.js']) }
2.15 output的path:
output有一個publicPath屬性,為項目中引用 css,js,img 等資源時候的一個基礎路徑。其輸出解析文件的目錄,指定資源文件引用的目錄 ,打包后瀏覽器訪問服務時的 url 路徑中通用的一部分。
output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', publicPath:'' },
2.16 devServer常用配置:
devServer:{ hot: true hotOnly:true, //默認端口 port:4000 //自動打開瀏覽器 open:false //開啟服務端壓縮 compress: true //使用 History 路由模式時,若404錯誤時被替代為 index.html historyApiFallback: true }
2.17 proxy代理:
通過webpack設置代理解決瀏覽器跨域問題。在 devServer 下添加一個 proxy 屬性:
devServer:{ .... proxy: { //定義一個標記,如以后api開頭的請求都走代理的設置 '/api': { // 要請求的真實服務端基地址 相當于被/api替代了 target: 'https://...', //把api重寫為空,因為別人沒有 /api pathRewrite: {"^/api":""}, //發送請求頭中host會設置成target changeOrigin: true } } }
此時,如果我們原本想請求的服務端地址為 https://… /user 就可以替換成 /api/user , 然后把/api重寫為空,那么實際上就是相當于寫了 https://… /user, 如:
axios.get('/api/user').then(res=>{...})
2.18 mode模式:
提供 mode 配置選項,告知 webpack 使用相應模式的一些內置優化。如果沒有設置,webpack 會給 mode 的默認值設置為 production。
string = 'production': 'none' | 'development' | 'production' module.exports = { mode: 'development', };

2.19 打包vue文件:
1.安裝:
$ cnpm i vue-loader vue-template-compiler -D
2.添加規則:
{ test:/\.vue$/, use:['vue-loader'] }
3.導入插件并使用:
const VueLoaderPlugin = require('vue-loader/lib/plugin');
未完結,持續更新中。。。
該文章在 2024/4/3 11:13:55 編輯過