一. 資源子產品(asset model)
1. 說明
資源子產品(asset module)是一種子產品類型,它允許使用資源檔案(字型,圖示等)而無需配置額外 loader。
(1). 在 webpack 5 之前,通常使用: (需要npm來安裝)
raw-loader 将檔案導入為字元串
url-loader 将檔案作為 data URI 内聯到 bundle 中
file-loader 将檔案發送到輸出目錄
(2). 在webpack5之後,新增資源子產品類型(asset module type),通過添加 4 種新的子產品類型,來替換所有這些 loader: (已經内置,不需要安裝)
asset/resource
發送一個單獨的檔案并導出 URL。之前通過使用 file-loader
實作。 asset/inline
導出一個資源的 data URI。之前通過使用 url-loader
asset/source
導出資源的源代碼。之前通過使用 raw-loader
asset
在導出一個 data URI 和發送一個單獨的檔案之間自動選擇。之前通過使用 url-loader
,并且配置資源體積限制實作。 【等價于:file-loader + url-loader 】
2. 常用PlaceHolders

3. 實戰-檔案解析打包
(1). 代碼準備
// 通過背景的模式設定圖檔
import "../font/iconfont.css";
const bgDivEl = document.createElement('div');
bgDivEl.className = "image-bg";
document.body.appendChild(bgDivEl);
// 通過src的模式設定img
import myImg from '../img/02.jpg';
const imgEl = document.createElement('img');
//注意,這裡必須用上面import的模式來寫,看做一個子產品,否則打包的時候,路徑就錯誤了
imgEl.src = myImg;
imgEl.height=140;
imgEl.width=140;
document.body.appendChild(imgEl);
css代碼
.image-bg {
background-image: url("../img/01.jpg");
background-size: contain;
width: 140px;
height: 140px;
}
View Code
(2). 相關配置
// 檔案解析功能,"asset/resource"(等價于file-loader )
{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset/resource",
generator: {
filename: "img/[name]_[hash:6][ext]"
}
},
補充:輸出路徑也可以全局配置
output: {
path: path.resolve(__dirname, "./build"), //打包後存放路徑, 必須寫絕對路徑
filename: "bundle.js", //打包後的檔案名稱
assetModuleFilename: "img/[name]_[hash:6][ext]" //全局配置資源子產品
}
(3). 打包測試即可
【npm run build】
4. 實戰-檔案轉換base64
可以将較小的檔案,轉成base64的URI,存放到打包後的js檔案裡
核心配置:
// 含轉換base64的功能 "asset", (等價于 file + url 兩個loader)
{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset",
generator: {
filename: "img/[name]_[hash:6][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 100 * 1024 //(表示100kb以下的檔案轉換成base64編碼)
}
}
},
5. 實戰-解析字型
核心配置 :
// 解析字型(也可以用file-loader處理)
{
test: /\.(eot|ttf|woff2?)$/,
type: "asset/resource",
generator: {
filename: "font/[name]_[hash:6][ext]"
}
},
其它代碼:
// 字型相關的使用
import "../font/iconfont.css";
const iEl = document.createElement('i');
iEl.className = "iconfont icon-ashbin";
document.body.appendChild(iEl);
補充:
(1). file-loader
【npm install file-loader -D】
{
test: /\.(jpe?g|png|gif|svg)$/,
use: {
loader: "file-loader",
options: {
// outputPath: "img",
name: "/img/[name]_[hash:6].[ext]",
}
}
},
(2). url-loader
【npm install url-loader -D】
{
test: /\.(jpe?g|png|gif|svg)$/,
use: {
loader: "url-loader",
options: {
// outputPath: "img",
name: "/img/[name]_[hash:6].[ext]",
limit: 100 * 1024 //100kb (表示100kb以下的圖檔轉換成base64編碼)
}
}
},
二. 常用插件
1. 什麼是插件
常用插件見:https://webpack.docschina.org/plugins/
2. CleanWebpackPlugin
(1). 作用:每次修改了一些配置,重新打包時,都需要手動删除打包後build的檔案夾。
(2). 核心配置
A. 指令安裝:【npm install clean-webpack-plugin -D】
B. 配置
// 導入插件
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
plugins: [
new CleanWebpackPlugin()
]
}
3. HtmlWebpackPlugin
(1). 作用:在打封包件夾裡自動生成一個入口頁面index.html
A. 指令安裝:【npm install html-webpack-plugin -D】
B. 配置
// 導入插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
plugins: [new HtmlWebpackPlugin({
title: "hello webpack"
})
]
}
總結:
上面的配置會預設生成一個index.html,預設情況下是根據ejs的一個模闆來生成的;在html-webpack-plugin的源碼中,有一個default_index.ejs子產品。
補充-自定義html模闆
比如建立public檔案夾,在裡面放上vue-cli建立的index.html作用模闆頁面,那麼就需要修改配置。。。
模闆頁面
<!DOCTYPE html>
<html lang="">
<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">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
配置檔案
// 導入插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
module: {
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
title: "hello webpack"
})
]
}
4. DefinePlugin
(1). 作用:DefinePlugin允許在編譯時建立配置的全局常量,是一個webpack内置的插件(不需要單獨安裝)
(2). 核心配置:
// 導入插件
const { DefinePlugin } = require("webpack");
module.exports = {
plugins: [new DefinePlugin({
BASE_URL: "'./'"
})
]
}
5. CopyWebpackPlugin
(1). 作用:通過這個插件,可以實作将自定義的public檔案夾中的檔案複制到build下,但是我又不想全複制,那麼就要配置一下忽略。
A. 指令安裝:【npm install copy-webpack-plugin -D】
// 導入插件
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [new CopyWebpackPlugin({
patterns: [{
from: "public", //設定從哪一個源中開始複制;
// to: "./", //複制到的位置,可以省略,會預設複制到打包的目錄下;
globOptions: { //下面配置忽略清單
ignore: [
"**/index.html"
]
}
}]
})
]
}
三. mode配置
1. 簡單說明
(詳見:https://webpack.docschina.org/configuration/mode/)
提供
mode
配置選項,告知 webpack 使用相應模式的内置優化。
2. 使用
預設情況下,假設有一句js代碼出錯了,打包後的檔案無法快速定位到哪裡出錯了,但是如果按照下面的方式配置一下,就可以定位了。
// 這裡必須通過 commonjs的寫法配置,不能寫 ES6的寫法
const path = require('path');
module.exports = {
// 設定模式, development 開發階段, 會設定development, production 準備打包上線的時候, 設定production(預設)
mode: "development",
// 設定source-map, 建立js映射檔案, 友善調試代碼和錯誤
devtool: "source-map",
entry: "./src/main.js", //入口檔案
output: {
path: path.resolve(__dirname, "./build"), //打包後存放路徑, 必須寫絕對路徑
filename: "bundle.js" //打包後的檔案名稱
},
}
如圖:
!
- 作 者 : Yaopengfei(姚鵬飛)
- 部落格位址 : http://www.cnblogs.com/yaopengfei/
- 聲 明1 : 如有錯誤,歡迎讨論,請勿謾罵^_^。
- 聲 明2 : 原創部落格請在轉載時保留原文連結或在文章開頭加上本人部落格位址,否則保留追究法律責任的權利。