1. 程式人生 > 其它 >asset module type 替代 loader 處理圖片字型等檔案資源

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: falsetype: "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的內容可以參考我其它的博文,持續更新中~