Leopold Kristjansson
Leopold Kristjansson

Reputation: 2784

Adding SVG Loader to Vue-cli project for a specific directory only

I am using Vue 2.6.10 in a vue-cli project. I want to use a SVG Loader in this project for SVG files from a specific directory only. These are my current rules in vue.config.js

  chainWebpack: (config) => {
    const svgRule = config.module.rule('svg')
    svgRule.uses.clear()
    svgRule
      .use('vue-svg-loader')
      .loader('vue-svg-loader')
  },

This works - but runs on all SVG files.

I've seen some include and exclude rules for webpack, but I am not sure how you would apply them in this context.

Upvotes: 1

Views: 1590

Answers (2)

MidnightTortoise
MidnightTortoise

Reputation: 464

I spent a long while trying to solve a similar problem myself.

Here's my solution:

chainWebpack: config => {
    /**
     * Ignore icons in the regular SVG rule
     *
     * It is necessary to use RegExp rather than a string literal
     * as WebPack complained about '!' being a reserved character 
     * when using literals
     */
    config.module.rule('svg').test(new RegExp(/^((?!\/icons\/).)*(svg)(\?.*)?$/));

    //Create a new rule for icons that converts them into Vue templates
    const svgIconRule = config.module.rule('svg-icon').test(new RegExp(/^.*(\/icons\/).*(svg)(\?.*)?$/));
    
    svgIconRule.uses.clear();
    svgIconRule.delete('type');
    svgIconRule.delete('generator');
    
    //Add replacement loader
    svgIconRule
        .use('vue-loader')
        .loader('vue-loader')
        .end()
        .use('vue-svg-loader')
        .loader('vue-svg-loader')
        .end()            
    ;
}

This will load all SVGs that don't contain icons in their path from the standard loader, and use vue-svg-loader for those that do.

Upvotes: 0

Kasheftin
Kasheftin

Reputation: 9423

https://github.com/neutrinojs/webpack-chain is in use here. The issue that I have is that after adding a restriction for vue-svg-loader I had to define the file-loader rule for all the other svg files.

I have two folders, /icons/inline for vue-svg-loader and /icons/plain for the default svgs that have to be served as files. This one works for me:

chainWebpack: (config) => {
  config.module.rule('svg').uses.clear()

  config.module
    .rule('svg')
    .test(/\/icons\/inline\/.*\.svg$/)
    .use('babel-loader')
      .loader('babel-loader')
      .end()
    .use('vue-svg-loader')
      .loader('vue-svg-loader')
      .end()

  config.module
    .rule('svg-file')
    .test(/\/icons\/plain\/.*\.svg$/)
    .use('file-loader')
      .loader('file-loader')
      .end()
}

Upvotes: 3

Related Questions