Webpack5 Asset Module 使用小结
我们常用 raw-loader、url-loader、file-loader 来处理图片、字体等资源文件,Webpack5 为我们提供了一种更简单、更方便的方式来替换上述 loader,这既是本文我们将要介绍的 Asset Module(即资源模块)。
分类
Webpack5 为我们提供了 asset/resource
、asset/inline
、asset/source
、asset
四种资源类型,具体介绍如下所示:
asset/resource
:将资源文件输出到指定的输出目录,作用等同于file—loader
;asset/inline
:将资源文件内容以指定的格式进行编码(一般为base64
),然后以 data URI 的形式嵌入到生成的bundle
中,作用等同于url-loader
;asset/source
:将资源文件的内容以字符串的形式嵌入到生成的bundle
中,作用相当于raw-loader
;asset
:作用等同于设置了limit
属性的url-loader
,即资源文件的大小如果小于limit
的值(默认值为8kb
),则采用asset/inline
模式,否则采用asset/resource
模式。
使用
基本使用
Asset Module 的使用非常简单,只需将之前的配置:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
};
调整为以下配置即可:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
type: 'asset' // 可用值:asset/resource、asset/inline、asset/source、asset
},
],
},
};
内联使用
除了通过配置文件,我们也可通过内联语法来使用相关 loader,比如:
// src/index.js
import avatar from 'file-loader!./avatar.png';
上例中,Webpack 将调用 file-loader
来处理资源 ./avatar.png
,那么在 Webpoack5 的 Asset Module 中又该如何进行内联操作呢?先看下面的例子:
// src/index.js
import avatar from './avatar.png?image';
// webpack.config.js
module.exports = {
module: {
rules: [
{
type: 'asset/resource',
resourceQuery: /image/,
},
],
},
};
通过例子可知,Webpack5 的 Asset Module 内联语法涉及以下两个步骤:
- 资源引用时加上
query
参数(比如上例中的?image
); - 在配置文件中添加
resourceQuery
配置项。
其中 resourceQuery
的常用格式为:
-
字符串
:上例的配置为?image
; -
正则表达式
:上例的配置为/image/
; -
对象
:{ and: [] }
:必须匹配数组中的所有条件;{ or: [] }
:只需匹配数组中的任一条件;{ not: [] }
:必须排除数组中的所有条件。
常用配置
assetModuleFilename
默认情况下,在处理 resource
类型的资源时,相关资源会被输出到 output.path 目录下(文件命名规则为 [hash][ext][query]
),我们可通过设置 output.assetModuleFilename
来改变其输出目录:
// webpack.config.js
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: './static/images/[hash][ext][query]',
},
};
这里需要注意的是,assetModuleFilename
的值须为相对路径
,如值为绝对路径
,将抛出以下异常:
Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.output.assetModuleFilename: A relative path is expected. However, the provided value "/home/nanjingboy/test-webpack/static/images/[hash][ext][query]" is an absolute path!
该配置仅适用于 asset
和 asset/resource
资源类型。
generator
在配置 module.rules
时,可配置 generator
来对资源的处理进行进一步控制,该配置有以下几个属性:
-
filename
:- 作用等同于上文所说的
output.assetModuleFilename
,值也必须为相对路径
; - 如果同时指定了该属性和
output.assetModuleFilename
,将忽略output.assetModuleFilename
的值;
- 作用等同于上文所说的
-
dataUrl
:- 在处理
inline
类型的资源时,该资源默认对资源进行base64
编码,可通过该属性来改变其编码方式; - 该属性值为函数,其签名为
(content: string) => string
; - 该属性仅适用于
asset
和asset/inline
资源类型。
- 在处理
上述配置的示例如下:
// webpack.config.js
module.exports = {
modules: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
type: 'asset',
generator: {
filename: './static/images/[hash][ext][query]',
dataUrl: content => {
return encode(content.toString());
},
},
},
],
},
};
parser.dataUrlCondition
在配置 module.rules
时,可通过 parser.dataUrlCondition
来决定是按照规则 asset/inline
,还是按照规则 asset/resource
来处理资源,该配置有以下两种用法:
-
指定
maxSize
属性:- 当
type
为asset
时,如果资源大小小于8kb
,按照asset/inline
的规则处理资源,否则按照asset/resource
的规则处理资源; - 可通过指定该属性来改变其界限值(单位为
byte
); - 该属性仅适用于
asset
资源类型。
// webpack.config.js module.exports = { modules: { rules: [ { test: /\.(png|jpe?g|gif)$/i, type: 'asset', parser: { dataUrlCondition: { maxSize: 4 * 1024 // 4kb,单位为 byte,默认值为 8kb }, }, }, ], }, };
- 当
-
指定一个函数:
- 该函数返回
boolean
类型(true
使用asset/inline
规则,false
使用asset/resource
规则): - 该属性仅适用于
asset
资源类型。
// webpack.config.js module.exports = { modules: { rules: [ { test: /\.(png|jpe?g|gif)$/i, type: 'asset', parser: { dataUrlCondition: (source, { filename, module }) => { // doSomething.... return true; }, }, }, ], }, };
- 该函数返回
总结
本文我们对 Webpack5 Asset Module(即资源模块)的使用进行了简短介绍,如有疏漏之处还望诸位海涵,祝大家快乐编码每一天。
转载自:https://juejin.cn/post/7116432242875826190