JetBrains / svg-mixer

Node.js toolset for generating & transforming SVG images and sprites in modern way
MIT License
175 stars 41 forks source link

How to use with Webpack 5 Asset Modules? #101

Open aminta opened 3 years ago

aminta commented 3 years ago

Hi, I can't use your plugin using Webpack 5 Asset Modules to treat Svg: the final Svg remains untouched, here it is my confguration:

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
  .BundleAnalyzerPlugin;
const CopyPlugin = require('copy-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const HtmlWebpackInlineSVGPlugin = require('html-webpack-inline-svg-plugin');
// const FontfacegenWebpackPlugin = require('fontfacegen-webpack-plugin');
const path = require('path');
const dev = process.env.NODE_ENV !== 'production';

module.exports = {
  entry: {
    main: path.resolve(__dirname, './src/app.js'),
  },
  output: {
    filename: '[name].[contenthash].bundle.js',
    path: path.resolve(__dirname, 'dist/assets/js'),
    publicPath: '',
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    port: 9000,
    writeToDisk: true,
    watchContentBase: true,
    open: 'Google Chrome',
  },
  devtool: dev ? 'eval-cheap-module-source-map' : 'source-map',
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, 'src/images'),
          to: 'assets/images',
          noErrorOnMissing: true,
          globOptions: {
            ignore: ['**/*.keep'],
          },
        },
      ],
    }),
    new CleanWebpackPlugin(),
    // new BundleAnalyzerPlugin(),
    new HtmlWebpackPlugin({
      title: 'Custom template',
      template: path.resolve(__dirname, 'src/root/index.html'),
    }),
    new HtmlWebpackInlineSVGPlugin({
      runPreEmit: true,
    }),
    new MiniCssExtractPlugin({
      filename: 'assets/css/[name].[contenthash].css',
      chunkFilename: '[name.css]',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
      {
        test: /\.(png|jpg)$/,
        type: 'asset',
        generator: {
          filename: 'assets/images/[hash][ext][query]',
        },
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf|svg)$/i,
        type: 'asset/resource',
        exclude: [/images/],
        generator: {
          filename: 'assets/fonts/[hash][ext][query]',
        },
      },
      {
        test: /\.svg/,
        type: 'asset',
        use: 'svg-transform-loader',
      },
      {
        test: /\.(scss)$/,
        use: [
          // {
          //   // inject CSS to page by injecting a `<style>` tag
          //   loader: 'style-loader'
          // },
          {
            loader: MiniCssExtractPlugin.loader, // extract Css to a file,
          },
          {
            // translates CSS into CommonJS modules - Interprets `@import` and `url()` like `import/require()` and will resolve them
            loader: 'css-loader',
          },
          {
            // Run postcss actions
            loader: 'postcss-loader',
            options: {
              // `postcssOptions` is needed for postcss 8.x;
              // if you use postcss 7.x skip the key
              postcssOptions: {
                // postcss plugins, can be exported to postcss.config.js
                plugins: function () {
                  return [require('autoprefixer')];
                },
              },
            },
          },
          {
            // compiles Sass to CSS
            loader: 'sass-loader',
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },
  optimization: {
    minimize: dev ? false : true,
    minimizer: dev ? [] : [new TerserPlugin(), new CssMinimizerPlugin()],
    // runtimeChunk: 'single',
    splitChunks: {
      // include all types of chunks
      chunks: 'all', //  adding optimization.splitChunks.chunks = 'all' is a way of saying “put everything in node_modules into a file called vendors~main.js".
    },
  },
};
JorisM commented 2 years ago

I'm facing the same issue. What I've found out so far:

I then looked at this.resourceQuery in loader.js

JorisM commented 2 years ago

changing it to const query = this.resourceQuery ? parseQuery(this.resourceQuery + this.resourceFragment) : null; seems to fix the problem for webpack 5