Vue Cli 3 не позволяет мне обрабатывать SVG в Webpack

Vue Cli по умолчанию file-loader для активов SVG, но я хочу использовать svg-sprite-loader (а также несколько других) вместо.

Я обновил vue.config.js файл, чтобы сделать это, и он все еще, кажется, использует file-loader, Почти как если бы он не собирал мой конфиг вообще.

vue.config.js

module.exports = {
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.(svg)(\?.*)?$/,
          use: [
            {
              loader: 'svg-sprite-loader',
              options: {
                name: '[name]-[hash:7]',
                prefixize: true
              }
            },
            'svg-fill-loader',
            'svgo-loader'
          ]
        }
      ]
    }
  }
}

Что-то не так с моей настройкой?

Я все еще получаю SVG-файлы, импортированные в мой компонент в виде строки / пути URL, когда это должен быть объект со свойствами.

Большое спасибо.

5 ответов

Решение

Это заняло у меня некоторое время, чтобы найти работу. По сути, вам нужно остановить сопоставление загрузчика файлов на.svg. Лучший способ, который я нашел, - это использовать chainWebpack и возвращать false из метода test в file-loader. Я включил мой рабочий конфиг.

module.exports = {
  lintOnSave: false,
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.(svg)(\?.*)?$/,
          use: [
            {
              loader: 'svg-inline-loader',
              options: {
                limit: 10000,
                name: 'assets/img/[name].[hash:7].[ext]'
              }
            }
          ]
        }
      ]
    }
  },
  chainWebpack: config => {
    config.module
      .rule('svg')
      .test(() => false)
      .use('file-loader')
  }
}

Документы Webpack для бета-версии Vue CLI 3.0 были обновлены с примером того, как заменить существующий базовый загрузчик. За svg-sprite-loader это означает, что вам придется добавить следующую конфигурацию в ваш vue.config.js:

chainWebpack: config => {
  config.module
    .rule('svg')
    .use('file-loader')
    .loader('svg-sprite-loader')
}

Я использую Vue CLI 3.0.3, и этот конфиг работает для меня

const path = require('path');
const glob = require('glob');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');

module.exports = {
  lintOnSave: false,
  configureWebpack: {
    plugins: [
      new SpriteLoaderPlugin()
    ]
  },
  chainWebpack: config => {
    config.module.rules.delete('svg');

    config
      .entry('app')
      .clear()
      .add(path.resolve(__dirname, './src/main.ts'))

    config
      .entry('sprite')
      .add(...glob.sync(path.resolve(__dirname, `./src/assets/icons/*.svg`)));

    config.module.rule('svg')
      .test(/\.(svg)(\?.*)?$/)
      .use('file-loader')
      .loader('svg-sprite-loader')
      .options({
        extract: true,
        spriteFilename: 'icons.svg'
      })
  }
};

Документы Vue CLI для версии 3.x в разделе webpack предлагают использовать что-то вроде этого:

// vue.config.js
module.exports = {
  chainWebpack: config => {
    const svgRule = config.module.rule('svg')

    // clear all existing loaders.
    // if you don't do this, the loader below will be appended to
    // existing loaders of the rule.
    svgRule.uses.clear()

    // add replacement loader(s)
    svgRule
      .use('vue-svg-loader')
      .loader('vue-svg-loader')
  }
}

Даже руководство по настройке vue-svg-loader предлагает такой же подход.

      module.exports = {
  chainWebpack: config => {
    const svgRule = config.module.rule('svg')

    svgRule.clear()

    svgRule
      .use('vue-svg-loader')
      .loader('vue-svg-loader')
  }
}
Другие вопросы по тегам