damianstasik / vue-svg-loader

🔨 webpack loader that lets you use SVG files as Vue components
https://vue-svg-loader.js.org
MIT License
645 stars 86 forks source link

Configure both internal and external loaders in 0.17.x #150

Open daniluk4000 opened 3 years ago

daniluk4000 commented 3 years ago

I will just leave it here for someone looking for usage in 0.17.x. It's almost the same, but without babel

Vue

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

    svgRule.uses.clear();

    svgRule
        .oneOf('inline')
        .resourceQuery(/inline/)
        .use('vue-loader')
        .loader('vue-loader')
        .end()
        .use('vue-svg-loader')
        .loader('vue-svg-loader')
        .end()
        .end()
        .oneOf('external')
        .use('file-loader')
        .loader('file-loader')
        .options({
            name: `assets/[name].[hash:8].[ext]`,
        });
},

Tested in Vue 2.x

Nuxt

        extend(config: any) {
            const svgRule = config.module.rules.find((rule: any) => rule.test.test('.svg'));

            svgRule.test = /\.(png|jpe?g|gif|webp)$/i;

            config.module.rules.push({
                test: /\.svg$/,
                oneOf: [
                    {
                        resourceQuery: /inline/,
                        use: [
                            'vue-loader',
                            'vue-svg-loader',
                        ],
                    },
                    // Add original url-loader config to resolve every other svg without inline query
                    svgRule.use[0],
                ],
            });

            return config;
        },
andreasvirkus commented 3 years ago

I'm trying to get it to work in the reverse - I want to load the SVG inline by default and only load it externally when the resource query is passed in. So I thought I'd need to switch the rule order, as otherwise oneOf would always match the inline import pattern first:

const svgRule = config.module.rule('svg')
svgRule.uses.clear()

svgRule
  .oneOf('external')
  .resourceQuery('/external/')
  .use('file-loader')
  .loader('file-loader')
  .options({ name: 'assets/[name].[hash:8].[ext]' })
  .end()
  .end()
  .oneOf('inline')
  .use('vue-loader') // or babel-loader on 0.16.0
  .loader('vue-loader')
  .end()
  .use('vue-svg-loader')
  .loader('vue-svg-loader')
  .end()
  .end()

So I could do

import ComponentIcon from './svg/icon.svg' // Can be used as <component-icon />
import IconPath from './svg/icon.svg?external' // Can be used as <img :src="iconPath" />

But i still get back a Vue instance for both imports (with both 0.16.0 & 0.17.*) 🤔 @visualfanatic or @daniluk4000 do you spot anything wrong with my rules?

anish2690 commented 2 years ago

@andreasvirkus try with


 svgRule
    .oneOf('external')
    .resourceQuery(/external/)
    .use('file-loader')
    .loader('file-loader')
    .options({ name: 'assets/[name].[hash:8].[ext]' })
    .end()
    .end()
    .oneOf('inline')
    .use('babel-loader')
    .loader('babel-loader')
    .end()
    .use('vue-svg-loader')
    .loader('vue-svg-loader')
    .end()
    .end()