在后面几篇文章中,咱们曾经根底的如何使用一个 webpack
与webpack-cli
从 0 到 1 搭建一个简略的 react 或者 vue 工程利用,其中咱们应用了加载文件,咱们在之前解决文件应用 file-loader
或者 url-loader
解决,url-loader
次要是能够针对图片文件大小进行有抉择的 base64
压缩,在 webpack5
中能够用内置的 Asset Modules
来解决图片资源
接下来咱们一起来探讨下 webpack5
中对于 Asset Modules 的那些事
注释开始 …
初始化根底我的项目
新建一个文件夹webpack-04-resource
,
npm init -y
咱们装置我的项目一些根底反对的插件
npm i webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader @babel
l/core -D
在根目录新建webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {filename: 'js/[name].js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development',
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {presets: ['@babel/env']
}
},
{test: /\.(png|jpg)$/i,
type: 'asset/resource'
}
]
},
plugins: [new CleanWebpackPlugin(),
new HtmlWebpackPlugin({template: './public/index.html'})
]
};
留神咱们加载图片没有应用 file-loader
与url-loader
,咱们应用的是 webpack5
内置的 asset/rosource
这个来解决
module.exports = {
module: {
rules: [
{test: /\.(png|jpg)$/i,
type: 'asset/resource'
}
]
}
}
在 index.js
中咱们插入一张图片
import img1Src from '../assets/images/1.png';
var appDom = document.getElementById('app');
const img = new Image();
img.src = img1Src;
appDom.appendChild(img);
ok,运行 npm run server
, 关上浏览器localhost:8080
咱们会发现,生成的图片地址就是<img src="http://localhost:8080/js/../b1640e009cff6a775ce5.png">
generator 配置
当初我想配置图片的默认输入地址与名字, 在 module.rules
中有一个 generator
的属性能够配置匹配图片输入的文件
// webpack.config.js
module.exports = {
module: {
rules: [
...
{test: /\.(png|jpg)$/i,
type: 'asset/resource',
generator: {filename: 'images/[name][ext]'
}
}
]
}
}
此时页面加载图片的门路就变成 <img src="http://localhost:8080/js/../images/1.png">
了
如果你的图片地址是上传到 cdn
上的,那么你能够这么做,然而这种做法是不是在我的项目中真的须要,还有待商讨,因为这样会导致利用所有的所有图片用 cdn
形式加载,如果我的项目中只是局部图片按需 cdn 加载,那么这种做法是不可取的。
{test: /\.(png|jpg)$/i,
// type: 'asset/resource'
type: 'asset',
parser: {
dataUrlCondition: {maxSize: 40 * 1024}
},
generator: {
publicPath: 'https://cdn/assets', // cdn 域名前缀
filename: 'images/[name][ext]'
}
}
自此页面的加载的图片就是<img src="https://cdn/assets/images/3.png">
assetModuleFilename
除了 generator.filename
形式,你也能够在 output
中退出 assetModuleFilename
配置来批改图片默认的地址, 不过留神这个属性只能是针对 rule
中设置的 type''asset/resource' | 'asset'
类型才失效。
module.exports = {
output: {filename: 'js/[name].js',
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: 'images/[name][ext]'
}
}
通常我的项目里咱们会把比拟小的图片间接坐 base64
加载,大的图片就间接输入加载,或者上传到 cdn
间接加载图片地址, 你能够在 rules
的generator.publicPath
设置地址图片地址。
因而我引入两张大小不一样的图片测试,批改一下index.js
import img1Src from '../assets/images/1.png';
import img3Src from '../assets/images/3.png';
function renderImage(imageSource) {const weakMap = new WeakMap();
var appDom = document.getElementById('app');
imageSource.forEach((src) => {const img = new Image();
weakMap.set(img, img);
if (weakMap.has(img)) {weakMap.get(img).src = src;
appDom.appendChild(img);
}
});
}
renderImage([img1Src, img3Src]);
咱们再批改下webpack.config.js
module.exports = {
module: {
rules: [
...
{test: /\.(png|jpg)$/i,
// type: 'asset/resource'
type: 'asset',
parser: {
dataUrlCondition: {maxSize: 40 * 1024}
}
}
]
}
}
在 rules
中减少 parser
属性,并且将 type
改成 asset
, 当咱们设置一个dataUrlCondition: {maxSize: 40 * 1024}
, 小于KB
就用 base64
加载了,大于 40KB
就间接用图片门路加载
因而咱们能够看到两张图片,一张图片是 base64
一张图片就走文件门路了。
所以在你的我的项目中你能够利用这个 parser.dataUrlCondition.maxSize
个性来优化图片资源,有些资源小图片就能够用 base64
来加载,这样能够缩小页面图片的资源申请
然而并不是所有的图片都要 base64
,base64
生成的字符串十分大,同时也是减少了 html
的体积,无奈利用缓存机制加载图片。
所以在优化的网页加载过程中,并不是全副都用 base64
来加载图片。
对于内置模块的几个参数
次要参考官网 asset-modules
webpack5 之前
- row-loader 将文件导入为字符串,比方导入.txt 类型的文件
- url-loader 将文件作为
Data Url
嵌入到打包后bundle.js
中,比方base64
文件 - file-loader 将文件输入目录,图片文件会被打包到指定目录中加载
webpack5 当初
用 asset module type
通过增加以下四种类型来代替以上loader
- asset/resource 导出独自的
url
, 是file-loader
的替代品 - asset/inline 导出资源 Data Url, 是
url-loader
的替代品 - asset/source 到处文件资源内容,是
row-loader
的替代品 - asset 在
url-loader
和file-loader
中抉择,配置parse.dataUrlCondition.maxSize
来输入图片资源是否base64
输入
总结
- 相比拟
webpack5
之前咱们加载图片资源文件应用file-loader
或者url-loader
在webpack5
中能够应用内置模块type: 'assets/resource'
- 基于 webpack5 内置模块
asset module type
来设置资源的加载 - 图片资源
base64
解决,依据图片资源的大小parse.dataUrlCondition.maxSize
来限度是否须要base64
输入 - 比拟
asset module type
几种模式区别,代替以前row-loader
、file-loader
、url-loader
计划,然而这仅仅是你的webpack
版本在 5 当前。 - 本文 code example