WebPack 图片处理

it2025-11-02  5

WebPack 图片处理

前言:在网页开发的过程中,经常需要处理各类图标。以前我们会使用png/jpg图片,压缩完转base64或直接使用。但是这样会出现一个重要的问题,就是我们的图标是模糊的,放大一定系数之后,这种缺陷会越发的明显。有鉴于此,取而代之的是 iconFont 以及 SVG 等技术。本文会比较各类图片处理技术,各自的使用场合,并说明如何结合 Webpack 使用它们进行网页开发。

PNG / JPG 等像素图片格式

使用

webpack

将切完的 PNG/JPG 等像素图片压缩后(tiny png)放入到项目中,利用 webpack url-loader 载入使用即可,配置如下:

{ test: /\.(png|jpe?g|gif)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } },

此处,options 配置了:

limit 设置让 webpack 在处理较小的图片(此处为 10 kb),将其转换成base64字符串

name 设置用于配置生成后的文件的命名(此处加入了长度为7的hash串)

CSS

利用 background url 引入使用即可:

/* 定义在元素上 */ .icon-logo { display: block; ... background: url(../assets/images/logo.png); } /* 定义在伪元素上 */ .icon-logo:before { content: ''; display: block; ... background: url(../assets/images/logo.png); }

PNG

适用场景:无损保存含有透明通道的像素图片(无法提供矢量图),若图片较小可直接转码为base64格式

优点:无损保存像素图片

缺点:文件较大,需压缩处理;像素图片在放大一定的系数后,都会显的模糊

JPG

适用场景:有损保存无透明通道的像素图片(无法提供矢量图),若图片较小可直接转码为base64格式。

优点:有损保存可以压缩图片大小

缺点:较原图有损,同时在放大后,会显的更加模糊

Base64 编码

当图片文件较小时,可以转换成内联的base64格式来使用,使用该方式载入图片有以下优点:

无需通过请求加载图片,能够减少大量的图片请求数,减少页面加载时间

可用于各类预加载场景Loading图

在样式类中内联使用非常方便,删除更新都非常方便,不会产生冗余图片

缺点:

base64字符串的大小会比原图大30%左右

无法提供对应的图片预览

IconFont

IconFont 是指将多个图标合并起来转换成字体文件,然后像使用文字一样使用它们,可以对这些图标使用很多文字效果。同时IconFont 图标放大后不会模糊,是非常流行一种图片处理技术。

使用

webpack

利用 webpack url-loader 载入:

{ test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } }

options 参数含义同上文所述。

CSS

定义 font-family 和对应的样式类来使用:

/* @font-face 定义 IconFont 字体 */ @font-face { font-family: 'IconFont'; src: url('./fonts/icon-font.eot'); src: url('./fonts/icon-font.eot') format('embedded-opentype'), url('./fonts/icon-font.woff2') format('woff2'), url('./fonts/icon-font.woff') format('woff'), url('./fonts/icon-font.ttf') format('truetype'), url('./fonts/icon-font.svg') format('svg'); font-weight: normal; font-style: normal; } /* 定义公用样式类 */ .icon-font { display: inline-block; font: normal normal normal 14px/1 IconFont; font-size: inherit; } /* 具体图标样式类(一般在伪元素中使用) */ .icon-font-edit:before { content: "\f040"; }

优缺点

优点

可以将多个图标 icon 合并成一个字体文件,减少图片请求次数

放大不会模糊(矢量图)

可以利用部分字体的样式来定制图标(如大小、颜色等)

缺点

一般只用于保存各类简易的图标,不支持单个大文件图片

需提供对应的矢量文件来生成字体文件,生成起来较繁琐,增删图标都需要进行重新生成

不同浏览器支持的字体文件格式不一样,CSS样式中需添加多个字体文件加载源

iconfont.cn

建议多使用 iconfont.cn 网站来生成和管理 IconFont 图标字体文件。

SVG

SVG 是一种网络矢量图片格式,SVG 图片放大不会模糊,同时支持很多矢量图片的操作(如填充、描边、蒙版等),是非常流行的一种图片处理技术,同时其生成和使用非常方便,已经有取代IconFont的趋势。

使用

Vue + Webpack

使用 vue-svg-loader 将 SVG 图片加载成 Vue 组件使用:

{ test: /\.svg$/, loader: 'vue-svg-loader', options: { svgo: { plugins: [ { cleanupIDs: { minify: false }, }, { removeViewBox: false } ] } } },

此处,options中是 vue-svg-loader 的配置信息,plugins 属性定义了使用的 svgo 模块的插件配置,此处禁用了 cleanupIDs 插件的压缩功能以及 viewBox 清除功能(会导致无法使用 width height 属性对 svg 进行缩放)。

说明:vue-svg-loader 使用 svgo 模块来优化和压缩 SVG 图片。svgo 会将 svg 图片内容转换为 js 对象(sax风格),然后利用各类定制插件对该对象进行处理,处理完毕后将该 js 对象再转换为 svg 图片,cleanupIDS 是 svgo 中 id 属性处理插件。

在 vue-svg-loader 的使用过程中,我发现了一个严重的问题,当网页上的 svg 图片较多,并且多个 svg 存在子元素有 id 属性的情况下,这些 id 属性在处理完之后会出现重复的现象,导致一些 svg 图片显示有问题,但是在 github 以及相关平台上未能找到解决方案,于是研究了一下该模块的源码,找出了对应的解决办法。

原因是 svgo 默认使用 cleanupIDs 来清理 svg 元素无用 id属性 或压缩其 id 属性为简单的字符串(如:a, b, c)。但是多个 svg 图片在压缩过程中就会出现重复的 id,在单个页面中出现多个这样的 svg 图片就会导致除了第一个 svg 显示正常以外,其它的 svg 图片无法正常显示。

所以需要禁用 cleanupIDs 插件 minify 压缩功能来确保页面显示正常。

Vue

在组件的 vue 文件中,按照以下形式使用该 SVG 组件:

<template> <div> ... <iconLogo class="icon-logo" /> ... </div> </template> <script> import iconLogo from '../assets/images/logo.svg'; export default { name: 'SVG', components: { iconLogo }, ... } </script> <style> .icon-logo { fill: #ff4500; } </style>

优缺点

优点

一般会压缩后内联使用,无需发送图片请求

放大不会模糊(矢量图)

可以使用大量的矢量图形操作

很容易从各类矢量图形设计软件中导出

结合 webpack 单个文件模块化处理方便,文件管理也很方便

缺点

一般只用于各类图标或简易图形,不支持单个大文件或富表现图片

矢量图片压缩空间有限,一般会比像素图片大

iconfont.cn

建议多使用 iconfont.cn 网站来搜索和使用 SVG 图标文件。

最新回复(0)