使用 svg-sprite-loader 引入 SVG 以及它的“坑”

9,484 阅读2分钟

在页面中以 symbol 引用的方式使用 SVG,已经成为目前最完美的图标解决方案。除了使用一些无版权图标网站如 Iconfont 提供的引入方式外,我们还可以在项目中使用 Webpack 来引入自己的 SVG,这就要用到 svg-sprite-loader。

svg-sprite-loader 的安装和配置

打开 svg-sprite-loader 的官方文档,可以看到它的安装方式:

npm install svg-sprite-loader -D
# via yarn
yarn add svg-sprite-loader -D

安装完成以后需要对其进行配置,如果项目中使用了 Webpack,直接参照文档的配置方法即可。如果使用了一些开发框架官方提供的脚手架工具如 Vue CLI,它的配置可能会稍微复杂一些,需要参考 Vue CLI 的配置方法。

以下是笔者在使用 Vue CLI 时进行的配置,在 vue.config.js 中加入:

module.exports = {
  lintOnSave: false,
  chainWebpack: config =>{
    const dir = path.resolve(__dirname, '.../icons目录')

    config.module
      .rule('svg-sprite')
      .test(/\.svg$/)
      .include.add(dir).end()
      .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end()
      
    config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
    
    config.module.rule('svg').exclude.add(dir)
  }
}

在引入时如果需要一次性引入整个目录的 SVG,可以这样做:

const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);

try {
    importAll(require.context('.../icons目录', true, /\.svg$/));
} catch (error) {
    console.log(error);
}

SVG 可能会自带一个 fill 属性,如果有此属性,那么引入后无法再通过 CSS 修改颜色。所以在引入前应将 fill 删掉。但是这样做太低效了!

好在有另一个 loader 可以帮助我们自动完成这一工作,那就是 svgo-loader。

安装:

npm install svgo-loader --dev
# via yarn
yarn add svgo-loader --dev

在vue.config.js中配置:

// 只需在以上use('svg-sprite-loader')的end()后面添加:
module.exports = { //...
    .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end()
    .use('svgo-loader').loader('svgo-loader')
        .tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]})).end()

//...
}

这样在引入 SVG 时就可以自动去除 fill 属性了,非常方便。




以上为笔者在项目开发中使用 SVG symbol 引用图标时遇到的一些问题,以及最后总结出的一种可行且较为通用的解决方案,可供大家参考。