Webpack 最出色的功能之一就是,除了引入 JavaScript,还可以利用内置的资源模块(Asset Modules)引入任何其他类型的文件。
资源模块(Asset Module)是一种模块类型,它允许我们应用 Webpack 来打包其他资源文件(如字体、图标等)。
4 种资源模块类型:
asset/resource:发送一个单独的文件并导出 URL;asset/inline:导出一个资源的 data URI;asset/source:导出资源的源代码;asset:在导出一个 data URI 和发送一个单独的文件之间自动选择。
一、Resource 资源
asset/resource:发送一个单独的文件并导出 URL。意思是,会将指定文件打包到 dist 目录且生成 url 供代码使用。
1. 基本配置
webpack.config.js:
module.exports = {
// 配置资源文件
module: {
rules: [
{
test: /\.jpg$/,
type: 'asset/resource'
}
]
},
}
入口文件 index.js:
import imgsrc from './assets/img-1.jpg'
const img = document.createElement('img')
img.width = 400
img.src = imgsrc
document.body.appendChild(img)
执行 npx webpack 后,发现 dist 目录中多了个 .jpg 文件:
执行 npx webpack serve --open 并在浏览器查看:
2. 自定义文件目录及文件名
默认情况下, asset/resource 模块以 [contenthash][ext][query] 文件名发送到输出目录。
[contenthash]:表示根据文件的内容,生成一个哈希的字符串;[ext]:表示使用原资源的扩展名;[query]:表示查询参数。
-
设置
output.assetModuleFilenamemodule.exports = { output: { assetModuleFilename: 'images/[contenthash][ext][query]' }, } -
将某些资源发送到指定目录
module.exports = { module: { rules: [ { test: /\.jpg$/, type: 'asset/resource', generator: { // 优先级高于 output 中的 assetModuleFilename filename: 'imgs/[contenthash][ext][query]' } } ] }, }
二、inline 资源
asset/inline:导出一个资源的 data URI。注意,这种方式不会将文件打包到 dist 目录中,而是生成 data URI,可以在浏览器中查看。
1. 基本配置
webpack.config.js:
module.exports = {
module: {
rules: [
{
test: /\.svg/,
type: 'asset/inline'
}
],
},
}
入口文件 index.js:
import svgsrc from './assets/svg-1.svg'
const img2 = document.createElement('img')
img2.src = svgsrc
document.body.appendChild(img2)
npx webpack 后执行 npx webpack serve --open 在浏览器中查看:
2. 自定义 data URI 生成器
Webpack 输出的 data URI,默认是使用 Base64 算法编码的,如果要使用自定义编码算法,则可以指定一个自定义函数来编码文件内容。
npm install mini-svg-data-uri -D
const svgToMiniDataURI = require('mini-svg-data-uri')
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
type: 'asset/inline',
generator: {
dataUrl: content => {
content = content.toString();
return svgToMiniDataURI(content);
}
}
},
]
},
}
现在,svg 文件都将经过 mini-svg-data-uri 进行编译处理。重新启动服务,在浏览器中可以发现,这次的 data URI 与上次已经不同了:
三、source 资源
asset/source:导出资源的源代码。
webpack.config.js:
module.exports = {
module: {
rules: [
{
test: /\.txt$/,
type: 'asset/source'
}
]
},
}
入口文件 index.js:
import exampleText from './assets/example.txt'
const block = document.createElement('div')
block.style.cssText = `width: 200px; height: 200px; background: aliceblue`
block.textContent = exampleText
document.body.appendChild(block)
启动服务,在浏览器中查看效果:
四、通用类型资源
asset:在导出一个 data URI(asset/inline) 和发送一个单独的文件(asset/resource)之间自动选择。
默认条件是:当文件小于 8kb 时,将会视 inline 模块类型,否则会被视为 resource 模块类型。
module.exports = {
module: {
rules: [
{
test: /\.png$/,
type: 'asset'
}
]
},
}
可以通过设置 Rule.parser.dataUrlCondition.maxSize 选项来修改自动选择的条件:
module.exports = {
module: {
rules: [
{
test: /\.png$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 400 * 1024 // 400kb
}
}
}
]
},
}
当文件大小小于 maxSize 指定的大小时,就会选择 asset/inline,生成 data URI:
当文件大小大于 maxSize 指定的大小时,就会选择 asset/resource,在 dist 目录中生成一个文件: