Webpack 5 走起! - Asset Modules(6) - asset/resource

前言

接下來將會關於靜態資源的部分,也就是圖片的搬移等。

Asset Modules (資產庫模組 or 存取模組)

Asset Modules 是 Webpack 5 新增的功能,其實如果你在 file-loader 的文件頁面下會看到這一句話

DEPRECATED for v5: please consider migrating to asset modules.

簡單來講就是 Webpack 5 已經棄用部分 loader 的方式,例如: url-loaderraw-loader 也是會看到這一條 「DEPRECATED for v5: please consider migrating to asset modules.」。

所以這一章節就來介紹一下 Asset Modules(資產庫模組 or 存取模組),在 Webpack 4 的時候我們都必須使用一些 Loader 模組來處理一些靜態資源,舉凡字型、圖片等。

而 Asset Modules 只要透過以下 Modules 來取代所有 loader

  • asset/resource - 對應 Webpack 4 的 file-loader,asset/resource 用途會比較偏向直接搬移檔案並外部連結到該檔案。
  • asset/inline - 對應 Webpack 4 的 url-loader,asset/inline 比較像是注入在這個檔案裡面,因此類似內部連結。
  • asset/source - 對應 Webpack 4 的 raw-loader
  • asset - 對應 Webpack 4 的 url-loader

因此接下來可以在 src 底下建立一個 assets/images 資料夾放置一張 .jpg 圖片,因此搬移圖片我們通常是使用 file-loader,那麼現在則改成以下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
mode: 'development',
entry: path.resolve(__dirname, './src/main.js'),
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash:6].bundle.js',
},
devServer: {
contentBase: path.resolve(__dirname, './dist'),
port: 3000,
compress: true,
open: true,
hot: true,
},
module: {
rules:[
{
test: /\.png/,
type: 'asset/resource'
}
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack 5',
template: path.resolve(__dirname, './src/template/index.html'),
filename: 'index.html',
inject: 'body',
}),
new CleanWebpackPlugin(),
]
};

接下來在 src/main.js 匯入該圖片

1
2
import testImg from './assets/images/brent-dalling-unsplash.png'; 
console.log(testImg); // output: http://localhost:3000/images/f368b8ee4b6f80a66ba9.png

接下來當你輸入 npm run build 應該就會看到 dist 底下出現你引入的圖片,如果使用 npm run dev 則可以看到 console.log 結果。

如果你希望是希望將常見的圖片都統一匯入的話,只需要將 test: /\.jpg/, 改成 test: /\.(png|jpg|gif)$/i, 就可以了。

接下來應該會發現我們匯入的圖片檔案是在 dist 資料夾,但我們通常開發編譯出來的圖片都會是在相對應的資料夾,例如圖片就在 dist/images 底下,那麼這一點只需要針對 output 增加一個 assetModuleFilename 就可以做到,而 assetModuleFilename 概念類似預設統一 Asset Module 輸出路徑

1
2
3
4
5
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash:6].bundle.js',
assetModuleFilename: 'images/[hash][ext]',
},

那麼以上就是最簡單的 asset/resource 設置,而結果就跟 file-loader 相同,可是可以看到撰寫方式簡潔相當多,在此你也可以回顧看一下原本的設置方式可能是這樣子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, './src/main.js'),
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].[contenthash:6].bundle.js',
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[name].[ext]',
},
},
],
},
],
},
};

參數說明

其實這邊有點跳痛沒有解釋 module 屬性中的 rulestesttype,因此最後這邊就補充一下

  • rules: 編譯 or 打包的規則,是一個陣列物件
  • test: 通常是一個 regex(正規表達式)
  • type: 你要使用的 Asset Modules 類型,通常有 asset/resourceasset/inlineasset/sourceasset

參考文獻

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ