Webpack 可以帮助我们处理项目中的图片。在之前的版本中,我们需要通过 url-loader
或者 file-loader
来处理图片资源,从 Webpack 5 开始,Webpack 内置了这些能力,我们只需要指定特定的选项就可以了。
type: "asset/inline"
将图片资源转成 base64 编码的形式保存在输出的代码中。这么做减少了页面请求数量,但是会增加构建输出的大小。该能力原来是url-loader
提供。type: "asset/resource"
与file-loader
能力相同,输出图片到单独的文件中。type: "asset/source"
与raw-loader
能力相同,返回模块的原始内容。type: "asset"
是type: "asset/inline"
和type: "asset/source"
的混合体,取决于资源的大小,与file-loader
的limit
功能相同。
output.assetModuleFilename
用来设置输出资源文件的名称,[hash][ext][query]
是三个占位符可选项,同时支持设置路径。
把图片添加到项目中
上面提到了各种处理图片的方式,下面是具体配置:
webpack.parts.js
exports.loadImages = ({ limit } = {}) => ({
module: {
rules: [
{
test: /\.(png|jpg)$/,
type: 'asset',
parser: { dataUrlCondition: { maxSize: limit } },
},
],
},
});
2
3
4
5
6
7
8
9
10
11
webpack.config.js
const commonConfig = merge([...parts.loadImages({ limit: 15000 })]);
测试一下我们配置,下载一张图片,然后添加到项目中。
src/main.css
body {
background: cornsilk;
background-image: url('./logo.png');
background-repeat: no-repeat;
background-position: center;
}
2
3
4
5
6
构建结果会根据 limit
的不同而不同。如果图片大小小于 limit
,则图片会被内联在构建输出的代码里,否则会被以单独的文件形式输出。
srcset
使用 现在浏览器支持给图片添加 srcset
属性,来根据不同条件使用不同的图片已达到最好的显示效果。可以通过 resize-image-loaderopen in new window, html-loader-srcsetopen in new window 和 responsive-loaderopen in new window 这几个包来实现这个功能。
优化图片
压缩图片可以有效减少生产环境的带宽占用,提升网站性能。如果你想压缩一下图片,则可以用这几个包,image-webpack-loaderopen in new window,svgo-loaderopen in new window(只适用于 svg),和 imagemin-webpack-pluginopen in new window. 注意,这些 loader 需要确保在最前面运行。
加载 SVG
Webpack 支持多种加载 svg 的方法,最简单的方法就是通过 type
:
const config = { test: /\.svg$/, type: 'asset' };
然后直接在样式中引用:
.icon {
background-image: url('../assets/icon.svg');
}
2
3
如下几个 loader 也可以实现加载 svg。
- svg-inline-loaderopen in new window 这个 loader 会删除 svg 中无用的标签。
- svg-sprite-loaderopen in new window 这个 loader 可以将多个 svg 合并到一个雪碧图中。这个 loader 同时也支持 .jpg 和 .png 图片。
- svg-url-loaderopen in new window 将 svg 图片以 UTF-8 编码的 data-url 形式输出,比 base64 编码性能更好。
- @svgr/webpackopen in new window 将 svg 图片以 React 组件的形式输出。
动态加载图片
Webpack 还支持动态加载图片,原理与代码按需加载的原理相同,后面会介绍。
加载雪碧图
雪碧图可以帮助我们将多个图片合并到一个图片中,减少网页请求数量。
webpack-spritesmithopen in new window 这个插件可以将多个图片合成为一个雪碧图,同时输出 Sass/Less/Stylus 的 mixins。我们需要在配置中添加 SpritesmithPlugin
插件,指向要组合额图片,同时制定一个输出的 mixins 名称,然后,代码中就可以使用雪碧图了。
@import "~sprite.sass";
.close-button {
sprite($close);
}
.open-button {
sprite($open);
}
2
3
4
5
6
7
8
9
使用图片占位符
image-trace-loaderopen in new window 这个包加载图片,同时以 image/svg+xml
的 url 编码的形式输出图片。与 file-loader
和 url-loader
一起使用,可以实现在请求真实图片的时候,先试用图片占位符显示。
lqip-loaderopen in new window 这个包实现的功能类似,但是 lqip-loader
会用一个模糊图片替代。
代码中如何使用图片
除了在样式中通过 @import
和 url()
的方式引用图片,在代码我们还可以这么用:
import src from './avatar.png';
const Profile = () => <img src={src} />;
2
3
从 Webpack 5 开始,我们还可以这么用:
const Profile = () => <img src={new URL('./avatar.png', import.meta.url)} />;
同时也可以动态加载图片
const src = require(`./avatars/\${avatar}`);
总结
通过 type
字段在调整不同资源的加载方式。在 Webpack 5 以前,通过 file-loader
和 url-loader
来实现。
通过根据图片的大小来决定图片输出的方式。
可以将多个小图片合并成一个雪碧图,来减少网络请求。
Webpack 还支持动态加载图片。
关注微信公众号,获取最新推送~
加微信,深入交流~