最近在做個 vue 的項目,從各種 github 上的開源庫上借鑒開發方法。
之前讀過 PanJiaChen 的項目 vue-admin-template,發現項目里對 svg 的使用很巧妙,只要在 src/icons/svg
文件夾下放入一個 svg 並引用組件SvgIcon
就能使用 svg 圖標。
於是我也想在我的項目中這么操作,但是不同之處是我的項目是基於 vue-cli 3 的,而作者的項目是自己配置的 webpack,所以我要在 vue-cli 3 的基礎上進行改造。費了點時間,所以還是把這次改動寫下來。
翻看作者的 webpack 配置,可以看到關於 svg 文件處理的配置是這樣寫的:
{ test: /\.svg$/, loader: 'svg-sprite-loader', include: [resolve('src/icons')], options: { symbolId: 'icon-[name]' } }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', exclude: [resolve('src/icons')], options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } },
作者使用了一個插件 svg-sprite-loader
對 svg 文件做處理,並指定了只對src/icons
下的 svg 做處理。在第二個對象中,svg 還用了 url-loader
做處理,但不對src/icons
下的 svg 做處理。(這里如果不想對 svg 使用 url-loader
的話其實可以在正則里不加 svg,不知道為什么作者還要做個 svg 的正則判斷)。
而在 vue-cli3 中,對 svg 的處理是:
webpackConfig.module .rule('svg') .test(/\.(svg)(\?.*)?$/) .use('file-loader') .loader('file-loader') .options({ name: genAssetSubPath('img') })
vue-cli 3 基於 webpack-chain ,使用了
file-loader
,並且把路徑指定為在
img
文件夾下,但我們的 svg 並不在
img
文件夾,而且
svg-sprite-loader
已經自帶了
file-loader
的功能,所以,我們可以在我們自定義的
vue.config.js
文件下將
rule(svg)
清除:
module.exports = { chainWebpack: config => { config.module.rule('svg').uses.clear() } }
然后加上自定義的 svg rule,最后的配置如下:
const path = require('path'); function resolve(dir) { // 路徑可能與你的項目不同 return path.join(__dirname, dir) } module.exports = { chainWebpack: config => { config.module .rule('svg') .uses.clear() config.module .rule('svg1') .test(/\.svg$/) .use('svg-sprite') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) .end() .include .add(resolve('src/icons')) .end() } }