支持热重载的svg生成iconfont字体图标插件

发布时间 2024-01-04 10:34:52作者: 居无常

【转】https://www.jianshu.com/p/909c9bd34e39

前言

之前生成iconfont字体图标,是用的https://icomoon.io/app/ 或者是阿里的https://www.iconfont.cn/ ,将UI给的svg图导入来生成。但是一直有个问题,假如需要再次加入几个图标时,又需要重新搞一遍,很麻烦。

而使用svg-sprite-loader的方式,也不是很方便,而且在body下插入一个超大的svg标签,影响性能不说,看着这么乱的代码真是挺难受。。而且有些UI库比使用字体图标会比较便利。另外字体文件特别是woff也比svg要小很多。

于是抽时间找了个webpack插件,自动用svg生成iconfont字体图标,支持热更新。

插件源码:webpack-iconfont-plugin-nodejs

执行以下命令,可直接查看插件效果:

git clone https://github.com/hzsrc/webpack-iconfont-plugin-nodejs.git
cd webpack-iconfont-plugin-nodejs
npm install
npm run dev

原理及用法

字体及css的生成流程:

 

热重载(hot-reload)流程:

 

 

使用这个插件后,开发时在src/iconfont/svgs目录下,修改或添加、删除svg文件时,就可以自动生成字体图标(支持ttf,woff2,woff,eot,svg)及配套从css样式、html预览了;同时热更新立即可以看到效果。

 

 

只需一个配置文件,并以此加入到webpack的plugins即可:

const WebpackIconfontPluginNodejs = require('webpack-iconfont-plugin-nodejs');
const path = require('path');
var dir = 'src/iconfont'
module.exports = new WebpackIconfontPluginNodejs({
  fontName: 'my-icon',
  cssPrefix: 'fii',
  svgs: path.join(dir, 'svgs/*.svg'),
  template: path.join(dir, 'css.njk'),
  fontsOutput: path.join(dir, 'fonts/'),
  cssOutput: path.join(dir, 'fonts/font.css'),
  htmlOutput: path.join(dir, 'fonts/_font-preview.html'),
  jsOutput: path.join(dir, 'fonts/fonts.js'),
  formats: ['ttf', 'woff', 'svg'],
})

项目中使用

别忘了最重要的一步,建立一个样式文件iconfont.css,建议全局引入

@font-face {
  font-family: "iconfont";
  src: url("../font/_font-preview/iconfont.eot?t=1591774693256"); /* IE9 */
  src: url("../font/_font-preview/iconfont.eot?t=1591774693256#iefix")
      format("embedded-opentype"),
    /* IE6-IE8 */ url("../font/_font-preview/iconfont.woff?t=1591774693256")
      format("woff"),
    url("../font/_font-preview/iconfont.ttf?t=1591774693256") format("truetype"),
    /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
      url("../font/_font-preview/iconfont.svg?t=1591774693256#iconfont")
      format("svg"); /* iOS 4.1- */
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 24px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.map-close::before {
  content: "\ea01";
}

.map-play::before {
  content: "\ea02";
}

然后在项目中直接使用 i 标签 + class 的方式可用:

<span class="video" @click="showDialog">
    <i class="iconfont map-play"></i>
</span>

从此告别 icomoon们!