jjmeyer's avatar

Using img-loader with mix to minify and data-url svg images

I am attempting to minify .svg images and to replace the image path with the data-url string in the compiled stylesheet.

What I have:

The pre-compiled tailwind css stylesheet contains reference to the .svg image

.si-background-svg {
    background-repeat: no-repeat;
    background-size: cover;
    pointer-events: none !important;
}

.si-icon-svg-activator {
    @apply si-background-svg;
    background-image: url('../svg/activator.svg');
}

What I am trying to achieve:

For image to be minified, and compiled into the ../public/css/app.css as:


.si-icon-svg-activator {
  background-repeat: no-repeat;
  background-size: cover;
  pointer-events: none;
  background-image: url("data:image/svg+xml;PHN2ZyB4bWxucz0iaHR0cDovL3d3dy.....
}

What I managed to achieve so far:

The actual image file is minified and copied to ../public/images/activator.svg

The image file activator.svg contains the following

module.exports = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0

The ../public/css/app.css contains the following:

.si-icon-svg-activator {
  background-repeat: no-repeat;
  background-size: cover;
  pointer-events: none;
  background-image: url("/images/activator.svg?62c469b7848d7a10b514417daca5015c");
}

The environment: I am using Laravel 7.5.15

I have npm installed url-loader img-loader imagemin-svgo imagemin

webpack.mix.js contains the following additional webpackConfig:

let mix = require('laravel-mix')
require('laravel-mix-purgecss')

mix.webpackConfig({
  module: {
    rules: [
      {
        test: /\.(svg)$/i,
        use: [
          'url-loader?limit=5000',
          {
            loader: 'img-loader',
            options: {
              plugins (context) {
                if (process.env.NODE_ENV === 'production') return []
                return [
                  require('imagemin-svgo')({
                    plugins: [
                      { cleanupIDs: false },
                    ]
                  })
                ]
              }
            }
          }
        ]
      }
    ]
  }
});


mix.js('resources/js/app.js', 'public/js')
  .postCss('resources/css/app.css', 'public/css')
  .postCss('resources/css/si-icon-svg.css', 'public/css')
  .options({
    postCss: [
      require('postcss-import')(),
      require('tailwindcss')(/* './path/to/tailwind.js' */),
      require('postcss-nesting')(),
    ]
  })
  .purgeCss({
    whitelistPatterns: [/^si-icon-svg.*/]
  })

if (mix.inProduction()) {
  mix.version()
}

It appears that I am halfway there, as the img-loader seems to minify (and base64 encode, which I'll still need to resolve) the .svg, but saves it back to the file instead of replacing the reference in the app.css.

I'd appreciate any pointers and assistance from anyone that may have encountered and resolved a similar use-case.

I am not able to use svg sprites or some of the other alternative workflows, due to the large number of images

0 likes
0 replies

Please or to participate in this conversation.