nuxt-community / svg-module

Super simple svg loading module for Nuxt.js
MIT License
338 stars 35 forks source link

Using ressourceQuery `/blockType=script/` to only convert to vue component svg inside `<script>` #81

Open mrleblanc101 opened 3 years ago

mrleblanc101 commented 3 years ago

Hi, Would it be possible to load svg inside script tag in SFC (import) as vue-component and all svg inside template using the default Nuxt loader ?

I feel like it would be possible using webpack ressource query but i wasn't actually able to make it work using ressourceQuery: /blockType=script/.

We use SVG in 3 way in our projet: 1) Inline in template using vue-svg-inline-loader: <img inline src="@/assets/svg/pin.svg" width="14" height="14" /> We have a SVGo config to strip the fill so we can change the svg color using CSS

2) Import inside our JS file using @nuxtjs/svg or vue-svg-loader. This is mostly when we have dynamic data and we want to display the correct component without having multiple v-if/v-else-if/v-else in the template with <component :is="componentName" />

3) Simple <img src="path/to/file.svg" /> but this is were this plugin come into conflict. We now need to use ?inline/?raw to make this work.

mrleblanc101 commented 3 years ago

Here what I tried:

const svgo = {
    plugins: [
        { prefixIds: true },
        { removeTitle: true },
        { removeDesc: true },
        { removeViewBox: false },
        { removeDimensions: true },
        {
            removeAttrs: {
                attrs: ['fill', 'opacity', 'stroke'],
            },
        },
    ],
};

...

build: {
    extend(config, ctx) {
        const svgRule = config.module.rules.find(rule => rule.test.test('.svg'));
        svgRule.test = /\.(png|jpe?g|gif|webp)$/;

        config.module.rules.push({
            test: /\\.svg$/,
            resourceQuery: /blockType=script/,
            use: [
            'vue-loader',
            {
                loader: 'vue-svg-loader',
                options: {
                    svgo,
                },
            },
            ],
        });

        config.module.rules.push({
            test: /\.vue$/,
            loader: 'vue-svg-inline-loader',
            options: {
                inlineKeyword: 'inline',
                inlineStrict: true,
                spriteKeyword: 'sprite',
                spriteStrict: true,
                removeAttributes: ['alt', 'src', 'inline'],
                xhtml: false,
                svgo,
            },
        });
    },
},