在 webpack 出现之前,前端开发人员会使用 grunt 和 gulp 等工具来处理资源,并
将它们从 /src 文件夹移动到 /dist 或 /build 目录中。webpack 最出色的功能之一就是,除了引入 JavaScript,还可以内置的资源模块 Asset Modules 引入任何其他类型的文件。
在webpack4的时候以及之前,我们通常是使用file-loader与url-loader来帮助我们加载其他资源类型。
1、Asset Modules Type的四种类型
而webpack5可以使用资源模块来帮助我们,称之为Asset Modules,它允许我们打包其他资源类型,比如字体文件、图表文件、图片文件等。
其中,资源模块类型我们称之为Asset Modules Type,总共有四种,来代替loader,分别是:
asset/resource:发送一个单独的文件并导出URL,替代file-loaderasset/inline:导出一个资源的data URI,替代url-loaderasset/source:导出资源的源代码,之前通过使用raw-loader实现asset:介于asset/resource和asset/inline之间,在导出一个资源data URI和发送一个单独的文件并导出URL之间做选择,之前通过url-loader+limit属性实现。
不过在介绍这四种资源模块类型之前,我们先说一下怎么自定义这些输出的资源模块的文件名
2、自定义资源模块名称
2.1、assetModuleFilename
第一种方式,就是在 webpack 配置中设置 output.assetModuleFilename 来修改此模板字符串
比如关于图片的输出文件名,我们可以让其都输出在images文件夹下面,[contenthash]表示文件名称,[ext]表示图片文件的后缀,比如.png、.jpg、.gif、jpeg等,[query]表可能存在的参数
output: {
···
assetModuleFilename: 'images/[contenthash][ext][query]'
···
},
2.2、geneator属性
第二种方式,就是在module.rules里面某种资源文件配置的时候,加上geneator属性,例如
rules: [
{
test: /\.png/,
type: 'asset/resource',
generator: {
filename: 'images/[contenthash][ext][query]'
}
}
]
【注意】
generator 的优先级高于 assetModuleFilename
3、四种类型的导入
首先我们先新建一个文件夹来测试,文件夹目录如下,我们在src下面新建一个assets文件夹,里面放上事先准备好的集中不同类型的图片

index.js
import hello from './hello'
import img1 from './assets/man.jpeg'
import img2 from './assets/store.svg'
import img3 from './assets/women.jpg'
import Txt from './assets/wenzi.txt'
import dynamic from './assets/dongtu.gif'
hello()
const IMG1 = document.createElement('img')
IMG1.src = img1
document.body.appendChild(IMG1)
const IMG2 = document.createElement('img')
IMG2.src = img2
IMG2.style.cssText = 'width:200px;height:200px'
document.body.appendChild(IMG2)
const IMG3 = document.createElement('img')
IMG3.src = img3
document.body.appendChild(IMG3)
const TXT = document.createElement('div')
TXT.textContent = Txt
TXT.style.cssText = 'width:200px;height:200px;backGround:aliceblue'
document.body.appendChild(TXT)
const DYNAMIC = document.createElement('img')
DYNAMIC.src = dynamic
document.body.appendChild(DYNAMIC)
hello.js
function hello(){
console.log("hello-world!!!")
}
export default hello
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>你是,永远的神</title>
</head>
<body>
</body>
</html>
webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry : './src/index.js',
output : {
filename:'bundle.js',
path:path.resolve(__dirname,'./dist'),
clean:true,
//如果不设置,打包完之后资源会直接打包在dist目录下
assetModuleFilename:'images/[contenthash][ext][query]'
},
mode : 'development',
devtool:'inline-source-map',
plugins:[
new HtmlWebpackPlugin({
template:'./index.html',
filename:'app.html',
inject:"body"
})
],
devServer:{
static:'./dist'
},
module:{
rules:[{
test:/\.jpeg$/,
type:"asset/resource",
generator:{
filename:'images/[contenthash][ext][query]'
}
},{
test:/\.svg$/,
type:'asset/inline'
},{
test:/\.txt$/,
type:'asset/source'
},{
test:/\.(gif|jpg)$/,
type:'asset',
parser:{
dataUrlCondition:{
maxSize : 10 * 1024 * 1024
}
}
}]
}
}
3.1、Resource 资源类型
asset/resource可以发送一个单独的文件并导出URL
我们将.jpeg后缀的图片设置type为asset/resource,我们在index.js里面导入该图片并插入在body中,即将其当成资源显示在页面上
npx webpack打包之后,dist文件夹下的images文件中就出现该图片

npx webpack-dev-server --open自动打开浏览器,我们在控制台中查看该图片类型,发现asset/resource类型确实可以导出一个文件和其URL路径

3.2、inline资源类型
asset/inline导出一个资源的data URI
仿照上面的方式,我们将.svg后缀的图片设置type为asset/inline,我们在index.js里面导入该图片并插入在body中,即将其当成资源显示在页面上,同时我们简单设置一下样式
不过不同的是,npx webpack打包之后,dist文件夹下面并没有打包过.svg类型的图片
npx webpack-dev-server --open自动打开浏览器,我们在控制台中查看该图片类型,发现asset/inline类型确实可以导出Data URI形式的路径

3.3、source资源类型
source资源,导出资源的源代码
仿照上面的方式,我们创建一个.txt后缀的文本文件,设置type为asset/source,我们在index.js里面导入该文本并插入在body中,即将其当成资源显示在页面上,同时我们简单设置一下样式
不过不同的是,npx webpack打包之后,dist文件夹下面并没有打包过.txt类型的文本文件
npx webpack-dev-server --open自动打开浏览器,我们在控制台中查看该文本类型,发现asset/source类型确实可以导出资源的源代码

3.4、asset通用资源类型
asset会介于asset/resource和asset/inline之间,在发送一个单独的文件并导出URL和 导出一个资源data URI之间做选择
默认情况下,webpack5会以8k为界限来判断:
- 当资源大于8k时,自动按
asset/resource来判断 - 当资源小于8k时,自动按
asset/inline来判断
我们可以手动更改临界值,设置parser(解析),其是个对象,里面有个固定的属性,叫dataUrlCondition,顾名思义,data转成url的条件,也就是转成bas64的条件,maxSize是就相当于Limit了
module:{
rules:[
···
{
test:/\.(gif|jpg)$/,
type:'asset',
parser:{
dataUrlCondition:{
maxSize : 100 * 1024
}
}
}
···
]
}
这里我们设置100 * 1024即100kb,来作为临界值
【1b * 1024 = 1kb,1kb * 1024 = 1M】
仿照上面的方式,我们将.gif和.jpg后缀的图片设置type为asset资源类型,我们在index.js里面导入2张图片并插入在body中,即将其当成资源显示在页面上,其中.gif大小为128.11kb(超过了100kb的临界值),.jpg大小为12kb(未超过100kb的临界值)
npx webpack打包之后,dist文件夹下面有打包过的.gif类型的图片,但是没有打包过.jpg类型的图片
npx webpack-dev-server --open自动打开浏览器,我们在控制台中查看2种图片类型,发现.gif图片是单独一个文件的URL路径,而.jpg图片是Data URI格式的base64路径

本博客参考:
本文介绍了Webpack 5中资产模块AssetModules的四种类型,包括resource、inline、source和通用的asset,以及如何自定义资源文件名。通过实例演示了如何在配置中使用assetModuleFilename和generator属性,展示了不同资源类型在打包过程中的行为。
118

被折叠的 条评论
为什么被折叠?



