asset module type 替代 loader 處理圖片字型等檔案資源
前面文章中 體驗了webpack的打包 、解析css資源 ,接下來看看專案中常用到的圖片、字型、檔案該怎麼處理吧~
專案路徑如下,在上一篇 解析css資源 專案基礎上增加了一些檔案
demo ├─ src │ ├─ css │ │ ├─ index.css │ │ └─ file.css (+) │ ├─ img │ │ ├─ portrait.png (+) │ │ └─ sky.jpg (+) │ ├─ js │ │ ├─ component.js │ │ └─ createElement.js (+) │ └─ index.js ├─ index.html ├─ package.json └─ webpack.config.js
在 createElement.js 分別建立一個 div 元素設定背景圖片、img 選擇引入圖片連結。
// createElement.js const imageEl = new Image(); const portrait = require("../img/portrait.png"); imageEl.src = portrait; document.body.appendChild(imageEl); const divEl = document.createElement("div"); divEl.style.width = "200px"; divEl.style.height = "200px"; divEl.className = "div-el"; document.body.appendChild(divEl); // file.css .div-el { background: url("../img/sky.jpg") top center/100% no-repeat; display: inline-block; } // index.css @import './file.css';
no loaders
直接通過 npm run build
是無法通過編譯的,會提示沒有合適的 loader 處理圖片資源
file-loader
file-loader 就是一個可以用來處理圖片字型等檔案資源的 loader,它的處理方式是將資源複製到打包後的資料夾,並重命名。
通過 npm i file-loader -D
安裝依賴,在 webpack.config.js 中配置
因為 file-loader 在webpack5 環境下已經棄用,要想正確處理圖片,需要配置兩個屬性。
- esModule: false (啟用 CommonJS 模組語法)
- type: "javascript/auto" (停止當前 asset 模組的處理,並再次啟動處理時,防止導致 asset 重複)
module.exports = {
// 其它配置省略
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: "file-loader",
options: {
// 定義複製後的檔名,取原檔名+雜湊值6位+原檔案字尾
name: "img/[name]_[hash:6].[ext]",
esModule: false,
},
},
],
type: "javascript/auto",
},
],
},
};
複製後的資源在 dist/img 資料夾下
在 html 頁面引入打包後的 js 檔案,通過 live server 可以看到圖片顯示在頁面上
url-loader
url-loader 是另一個可以處理圖片字型等檔案資源的 loader,它與 file-loader 有些不同
- file-loader 會複製所有的資源
- url-loader 只會複製佔用空間較大的資源,當資源較小時,會對它進行 base64 編碼
通過 npm i url-loader -D
安裝依賴,在 webpack.config.js 中配置
url-loader 和 file-loader 一樣,在webpack5環境下已經棄用,也需要配置 esModule: false
、type: "javascript/auto"
屬性
module.exports = {
// 其它配置省略
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
{
loader: "url-loader",
options: {
name: "[name]_[hash:6].[ext]",
// 自定義轉成 base64 資源大小,超過 limit 將直接複製資源
limit: 100 * 1024,
esModule: false,
},
},
],
type: "javascript/auto",
},
],
},
};
sky.jpg 大小為576kb,portrait.png 為33.2kb,所以 portrait.png 是以 base64 編碼的形式展現,sky.jpg 被複制到了打包後的資料夾 img 中
asset module type
在webpack5環境下棄用的 url-loader、file-loader,使用 asset module type 來替代,無需安裝依賴,直接在 webpack.config.js 中配置
asset module type 有以下幾種型別來對應 url-loader、file-loader
- asset/resource 實現同 file-loader,複製資源
- asset/inline 實現同 url-loader,自定義複製資源還是處理成 base64編碼
- asset 實現同url-loader,根據檔案大小自動處理
asset module type 的配置會稍微簡單一些
module.exports = {
// 其它配置省略
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
type: "asset",
// 對複製後的資源重新命名
generator: {
filename: "img/assetmodule.[name][ext]",
},
},
],
},
};
type為asset 時,大小為576kb的 sky.jpg 和 33.2kb 的 portrait.png 都被直接複製了
字型資源
以上方式也都可以處理字型資源,從 iconfont 上選取圖示儲存到自己專案並下載到本地
將iconfont.css及ttf、woff檔案放到src目錄下新增font資料夾中,在 createElement.js 中建立標籤、index.css 中引入 iconfont 樣式資源
// createElement.js
const addIcon = document.createElement("i");
addIcon.className = "iconfont icon-add";
document.body.appendChild(addIcon);
const deleteIcon = document.createElement("i");
deleteIcon.className = "iconfont";
deleteIcon.innerHTML = "";
document.body.appendChild(deleteIcon);
// index.css
@import '../font/iconfont.css'
使用 asset module type 來對字型資源進行配置
module.exports = {
// 其它配置省略
module: {
rules: [
{
test: /\.(ttf|woff2?)$/i,
type: "asset/resource",
generator: {
filename: "font/[name]_[hash:6][ext]",
},
},
],
},
};
兩個小圖示就能在頁面上展示了
音視訊等其它資源也都可以使用 file-loader、url-loader、asset module type 處理,親測有效~
以上就是處理圖片字型等檔案資源的方式,更多有關webpack的內容可以參考我其它的博文,持續更新中~