Webpack 资源模块
资源模块(asset module) 是一种模块类型,它允许使用资源文件(icon,img)而无需配置额外的loader。
资源模块类型(asset module type) 通过添加四种新的模块类型来替换所有这些loader:
- asset/resource 发送一个单独的文件并导出 URL,之前通过 file-loader 实现
- asset/inline 导出一个资源的 data URL,之前通过 url-loader 实现
- asset/source 导出资源 源代码,之前通过 raw-loader 实现
- asset 在导出一个 data URL 和发送一个 单独文件 之间自动选择,之前通过 url-loader 实现
asset/resource
发送一个单独的文件并导出 URL,之前通过 file-loader 实现配置
我们在 webpack.config.js 中配置 module 模块: ```javascript const path = require(‘path’) const HtmlWebpackPlugin = require(‘html-webpack-plugin’); // 引入 html-webpack-plugin 插件
module.exports = { entry: ‘./src/index.js’, // 入口文件路径 output: { // 出口文件 filename: ‘bundle.js’, // 出口文件名 path: path.resolve(__dirname, ‘./dist’), // 出口文件路径 clean: true // 生成新文件的同时是否删除旧文件 }, mode: ‘development’, // 设置模式 ‘none’ | ‘development’ | ‘production’ devtool: ‘inline-source-map’, // 帮助定位错误源文件位置 plugins: [ new HtmlWebpackPlugin({ // 实例化 HtmlWebpackPlugin,它将帮我们生成一个 dist/index.html 文件 template: ‘./index.html’, // 指定模板 filename: ‘index.html’, // 生成的文件名 inject: ‘body’ // script标签的生成位置 }) ], devServer: { static: ‘./dist’ // 路径 }, module: { rules: [ // 配置资源模块 { test: /.png$/, // 利用正则匹配以 .png 结尾的文件 type: ‘asset/resource’ // 设置资源模块类型 } ] } }
<a name="VLetS"></a>
#### 准备
我们把提前准备好的一些资源文件放到 src 中:<br />
<a name="iMXsY"></a>
#### 加载
我们在index.js中加载这个模块
```javascript
import Hello from './hello'
import imgSrc from './asset/web.png' // 返回一个 url
Hello()
const img = document.createElement('img') // 创建一个 img标签
img.src = imgSrc // 将返回的 url 设置给 img标签 的 src 属性
document.body.appendChild(img) // 在 body 中加入 img标签
打包
我们运行 npx webpack
从新打包,然后在dist下发现有一个 png 的文件,打开页面发现图片正常显示了,我们选中元素查看发现 asset/resource 确实导出了一个 URL
修改生成资源文件名
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入 html-webpack-plugin 插件
module.exports = {
entry: './src/index.js', // 入口文件路径
output: { // 出口文件
filename: 'bundle.js', // 出口文件名
path: path.resolve(__dirname, './dist'), // 出口文件路径
clean: true // 生成新文件的同时是否删除旧文件
},
mode: 'development', // 设置模式 'none' | 'development' | 'production'
devtool: 'inline-source-map', // 帮助定位错误源文件位置
plugins: [
new HtmlWebpackPlugin({ // 实例化 HtmlWebpackPlugin,它将帮我们生成一个 dist/index.html 文件
template: './index.html', // 指定模板
filename: 'index.html', // 生成的文件名
inject: 'body' // script标签的生成位置
})
],
devServer: {
static: './dist' // 路径
},
module: {
rules: [ // 配置资源模块
{
test: /\.png$/, // 利用正则匹配以 .png 结尾的文件
type: 'asset/resource', // 设置资源模块类型
generator: { // 修改生成资源文件名
filename: 'images/[contenthash][ext]' // contenthash 表示随机生成hash字符串作为文件名,ext 表示生成文件的后缀和源文件保持一致
}
}
]
}
}
asset/inline
导出一个资源的 data URL,之前通过 url-loader 实现
实现和 asset/resource 一样
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入 html-webpack-plugin 插件
module.exports = {
entry: './src/index.js', // 入口文件路径
output: { // 出口文件
filename: 'bundle.js', // 出口文件名
path: path.resolve(__dirname, './dist'), // 出口文件路径
clean: true // 生成新文件的同时是否删除旧文件
},
mode: 'development', // 设置模式 'none' | 'development' | 'production'
devtool: 'inline-source-map', // 帮助定位错误源文件位置
plugins: [
new HtmlWebpackPlugin({ // 实例化 HtmlWebpackPlugin,它将帮我们生成一个 dist/index.html 文件
template: './index.html', // 指定模板
filename: 'index.html', // 生成的文件名
inject: 'body' // script标签的生成位置
})
],
devServer: {
static: './dist' // 路径
},
module: {
rules: [ // 配置资源模块
{
test: /\.png$/, // 利用正则匹配以 .png 结尾的文件
type: 'asset/resource', // 设置资源模块类型
generator: {
filename: 'images/[contenthash][ext]' // contenthash 表示随机生成hash字符串作为文件名,ext表示生成文件的后缀和源文件保持一致
}
},
{
test: /\.svg$/, // 利用正则匹配以 .svg 结尾的文件
type: 'asset/inline', // 设置资源模块类型
}
]
}
}
import Hello from './hello'
import imgSrc from './asset/web.png' // 返回一个 url
import logoSvg from './asset/web.svg' // 返回 data url
Hello()
const img = document.createElement('img') // 创建一个 img标签
img.src = imgSrc // 将返回的 url 设置给 img标签 的 src 属性
document.body.appendChild(img) // 在 body 中加入 img标签
const img2 = document.createElement('img')
img2.src = logoSvg
document.body.appendChild(img2)
选中元素查看发现确实是 data url 是base64 格式的
asset/source
导出资源 源代码
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入 html-webpack-plugin 插件
module.exports = {
entry: './src/index.js', // 入口文件路径
output: { // 出口文件
filename: 'bundle.js', // 出口文件名
path: path.resolve(__dirname, './dist'), // 出口文件路径
clean: true // 生成新文件的同时是否删除旧文件
},
mode: 'development', // 设置模式 'none' | 'development' | 'production'
devtool: 'inline-source-map', // 帮助定位错误源文件位置
plugins: [
new HtmlWebpackPlugin({ // 实例化 HtmlWebpackPlugin,它将帮我们生成一个 dist/index.html 文件
template: './index.html', // 指定模板
filename: 'index.html', // 生成的文件名
inject: 'body' // script标签的生成位置
})
],
devServer: {
static: './dist' // 路径
},
module: {
rules: [ // 配置资源模块
{
test: /\.png$/, // 利用正则匹配以 .png 结尾的文件
type: 'asset/resource', // 设置资源模块类型
generator: {
filename: 'images/[contenthash][ext]' // contenthash 表示随机生成hash字符串作为文件名,ext表示生成文件的后缀和源文件保持一致
}
},
{
test: /\.svg$/, // 利用正则匹配以 .svg 结尾的文件
type: 'asset/inline', // 设置资源模块类型
},
{
test: /\.txt$/, // 利用正则匹配以 .txt 结尾的文件
type: 'asset/source', // 设置资源模块类型
}
]
}
}
我们在 asset 文件夹下新建一个 test.txt 文件:
hello 索大
剩下的和 asset/resource 相同:
import Hello from './hello'
import imgSrc from './asset/web.png' // 返回一个 url
import logoSvg from './asset/web.svg' // 返回 data url
import testTxt from './asset/test.txt' // 返回 源文件
Hello()
const img = document.createElement('img') // 创建一个 img标签
img.src = imgSrc // 将返回的 url 设置给 img标签 的 src 属性
document.body.appendChild(img) // 在 body 中加入 img标签
const img2 = document.createElement('img')
img2.src = logoSvg
document.body.appendChild(img2)
const block = document.createElement('div')
block.textContent = testTxt
document.body.appendChild(block)
asset
在导出一个 data URL 和发送一个 单独文件 之间自动选择,也就是 asset/resource 和 asset/inline。
默认情况下:小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。
我们可以通过配置 parser 来修改边界值,如下:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入 html-webpack-plugin 插件
module.exports = {
entry: './src/index.js', // 入口文件路径
output: { // 出口文件
filename: 'bundle.js', // 出口文件名
path: path.resolve(__dirname, './dist'), // 出口文件路径
clean: true // 生成新文件的同时是否删除旧文件
},
mode: 'development', // 设置模式 'none' | 'development' | 'production'
devtool: 'inline-source-map', // 帮助定位错误源文件位置
plugins: [
new HtmlWebpackPlugin({ // 实例化 HtmlWebpackPlugin,它将帮我们生成一个 dist/index.html 文件
template: './index.html', // 指定模板
filename: 'index.html', // 生成的文件名
inject: 'body' // script标签的生成位置
})
],
devServer: {
static: './dist' // 路径
},
module: {
rules: [ // 配置资源模块
{
test: /\.png$/, // 利用正则匹配以 .png 结尾的文件
type: 'asset/resource', // 设置资源模块类型
generator: {
filename: 'images/[contenthash][ext]' // contenthash 表示随机生成hash字符串作为文件名,ext表示生成文件的后缀和源文件保持一致
}
},
{
test: /\.svg$/, // 利用正则匹配以 .svg 结尾的文件
type: 'asset/inline', // 设置资源模块类型
},
{
test: /\.txt$/, // 利用正则匹配以 .txt 结尾的文件
type: 'asset/source', // 设置资源模块类型
},
{
test: /\.jpg$/, // 利用正则匹配以 .jpg 结尾的文件
type: 'asset', // 设置资源模块类型
parser: { // 修改边界值
dataUrlCondition: {
maxSize: 4 * 1024 * 1024 // 改为 4MB
}
}
}
]
}
}
import Hello from './hello'
import imgSrc from './asset/web.png' // 返回一个 url
import logoSvg from './asset/web.svg' // 返回 data url
import testTxt from './asset/test.txt' // 返回 源文件
import imgFree from './asset/web.jpg' // 自动选择
Hello()
const img = document.createElement('img') // 创建一个 img标签
img.src = imgSrc // 将返回的 url 设置给 img标签 的 src 属性
document.body.appendChild(img) // 在 body 中加入 img标签
const img2 = document.createElement('img')
img2.src = logoSvg
document.body.appendChild(img2)
const block = document.createElement('div')
block.textContent = testTxt
document.body.appendChild(block)
const img3 = document.createElement('img')
img3.src = imgFree
document.body.appendChild(img3)