目前为止,我们的项目可以在控制台上显示"Hello world"。现在我们尝试混合一些其他资源,比如images
,看看webpack如何处理。
在webpack出现之前,前端开发人员会使用grunt
和gulp
等工具来处理资源,并将它们从/src
文件夹移动到/dist
或/build
目录中。
webpack
最出色的功能之一就是,除了引入JavaScript
,还可以内置的资源模块asset module
引入任何其他类型的文件。
资源模块(asset module)是一种模块类型,它允许我们应用Webpack
来打包其他资源文件(字体,图标等)而无需配置额外 loader。
在 webpack 5 之前,通常使用:
raw-loader
将文件导入为字符串url-loader
将文件作为 data URI 内联到 bundle 中file-loader
将文件发送到输出目录
资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
asset/resource
发送一个单独的文件并导出 URL。之前通过使用file-loader
实现。asset/inline
导出一个资源的 data URI。之前通过使用url-loader
实现。asset/source
导出资源的源代码。之前通过使用raw-loader
实现。asset
在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用url-loader
,并且配置资源体积限制实现。
1. asset/resource
修改 webpack.config.js
配置:
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource'
}
]
}
index.js
引入图片资源
// src/index.js
import icon from './assets/icon.png'
const iconImg = document.createElement('img')
iconImg.style.cssText = 'width: 200px;'
iconImg.src = icon
document.body.appendChild(iconImg)
执行webpack
可以在dist
中可以看到有一个.png
文件出现,即为asset/resource
发送一个单独的文件
执行npx webpack-dev-server
可以看到图片已经出现,打开控制台查看elements可以看到改img标签的加载了url资源,即为asset/resource
导出 URL
2. 自定义输出文件名
2.1 默认情况下,asset/resource
模块以 [hash][ext][query]
文件名发送到输出目录。
可以通过在 webpack 配置中设置 output.assetModuleFilename
来修改此模板字符串:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
+ assetModuleFilename: 'images/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource'
}
]
},
};
执行webpack
可以看到dist/images
2.2 另一种自定义输出文件名的方式是,将某些资源发送到指定目录:
onst path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
+ assetModuleFilename: 'images/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource',
+ generator: {
+ filename: 'images/[hash][ext][query]'
+ }
}
]
},
};
使用此配置,所有 png
文件都将被发送到输出目录中的 images
目录中。
Rule.generator.filename
与 output.assetModuleFilename
相同,并且仅适用于 asset
和 asset/resource
模块类型。
但Rule.generator.filename
优先级高于 output.assetModuleFilename
3. asset/inline
webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource',
generator: {
filename: 'images/[hash][ext][query]'
}
},
+ {
+ test: /\.svg$/,
+ type: 'asset/inline'
+ }
]
}
}
idnex.js
import empty from './assets/empty.svg'
const emptyImg = document.createElement('img')
emptyImg.style.cssText = 'width: 200px;'
emptyImg.src = empty
document.body.appendChild(emptyImg)
执行webpack
,可以看到dist
中并没有新增加任何资源,
执行npx webpack-dev-server
可以看到图片显示出来了,并且图片base:64
。
asset/inline
只导出一个资源的 data URI,不会导出文件
4. asset/source
webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource',
generator: {
filename: 'images/[hash][ext][query]'
}
},
{
test: /\.svg$/,
type: 'asset/inline'
},
+ {
+ test: /\.txt$/,
+ type: 'asset/source'
+ }
]
}
}
assets
下新建 hello-webapck.txt
src/index.js
import helloWebpack from './assets/hello-webapck.txt'
const text = document.createElement('p')
text.style.cssText = 'width: 200px;height: 200px;background-color: pink;'
text.innerText = helloWebpack
document.body.appendChild(text)
执行webpack
,在dist/images
中没有新增资源
执行npx webpack-dev-server
可以看到hello webpack
显示在页面上了
asset/source
导出资源的源代码
5. asset 通用资源类型
webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource',
generator: {
filename: 'images/[hash][ext][query]'
}
},
{
test: /\.svg$/,
type: 'asset/inline'
},
{
test: /\.txt$/,
type: 'asset/source'
},
+ {
+ test: /\.jpeg$/,
+ type: 'asset'
+ }
]
}
}
src/index.js
import figure from './assets/figure.jpeg'
const figureImg = document.createElement('img')
figureImg.style.cssText = 'width: 200px;'
figureImg.src = figure
document.body.appendChild(figureImg)
执行webpack
,在dist/images
可以看到有新的图片,打开可以看到是我们刚刚加载的图片
执行npx webpack-dev-server
可以看到新图片显示在页面上了
现在,webpack
将按照默认条件,自动地在 resource
和 inline
之间进行选择:小于 8kb 的文件,将会视为 inline
模块类型,否则会被视为 resource
模块类型。
可以通过在 webpack
配置的 module rule
层级中,设置 Rule.parser.dataUrlCondition.maxSize
选项来修改此条件:
webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.jpeg$/,
type: 'asset',
+ parser: {
+ dataUrlCondition: {
+ maxSize: 4 * 1024 // 4kb
+ }
}
}
]
}
}
源码地址:https://gitee.com/yanhuakang/webpack-test
如果有用,就点个赞吧(*^▽^*)