在 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路径
本博客参考: