SVG sprite issue with Laravel Mix

1.1k views Asked by At

I'm struggled with the following and would appreciate any help...!

I try to use Laravel Mix (v5.0.4) and extend it with SVG sprite loader (svg-sprite-loader) to generate SVG sprite. I have the following folder structure:

resources/
  images/
    image.jpg
  sass/
    app.scss
  svg/
    file1.svg
    file2.svg

webpack.sprite.js
webpack.mix.js

The content of webpack.mix.js:

const mix = require('laravel-mix');
require('./webpack.sprite');

const toCss = 'public/css';

mix.sass('resources/sass/app.scss', toCss)
   .options({
       sassOptions: {
           outputStyle: 'nested',
       }
   })
   .sprite();

The content of webpack.sprite.js:

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

class Sprite {
    dependencies() {
        return ['svg-sprite-loader'];
    }

    webpackPlugins() {
        return new SpriteLoaderPlugin({plainSprite: true});
    }

    webpackRules() {
        return {
            test: /\.svg$/,
            include: path.resolve(__dirname, 'resources', 'svg'),
            use: [
                {
                    loader: 'svg-sprite-loader',
                    options: {
                        extract: true,
                        spriteFilename: path.resolve(__dirname, 'resources', 'images') + 'sprite.svg',
                        runtimeCompat: true
                    }
                },
                'svg-transform-loader',
                'svgo-loader'
              ]
        };
    }
}

mix.extend('sprite', new Sprite());

It does NOTHING in regards sprite, but it generates the CSS from SASS! :( I don't know why... Tried to "debug" it with some console.log() in the extension and it was hit, I saw the log messages in the console. But the sprite wasn't generated.

I also tried to use just hardcoded, relative paths in the extension without path. Didn't help.

Any idea?

Thanks in advance!

1

There are 1 answers

0
Devin Olsen On

I have a feeling this is related to Webpack5's new Asset module.

https://webpack.js.org/guides/asset-modules/

For assets to be written to disk, or possibly primed to be handed off to large plugins you need to now specify asset type and generator to best define a filename for these assets.

webpackRules() {
    return {
        test: /\.svg$/,
        include: path.resolve(__dirname, 'resources', 'svg'),
        type: 'asset/resource',
        generator: {
          'filename': '[name][ext]'
        },      
        use: [
            {
                loader: 'svg-sprite-loader',
                options: {
                    extract: true,
                    spriteFilename: path.resolve(__dirname, 'resources', 'images') + 'sprite.svg',
                    runtimeCompat: true
                }
            },
            'svg-transform-loader',
            'svgo-loader'
          ]
    };
}

If still no luck try an alternative plugin: https://www.npmjs.com/package/webpack-svg-spritely