Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use with Webpack 5 Asset Modules? #101

Open
aminta opened this issue Jan 27, 2021 · 2 comments
Open

How to use with Webpack 5 Asset Modules? #101

aminta opened this issue Jan 27, 2021 · 2 comments

Comments

@aminta
Copy link

aminta commented Jan 27, 2021

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
Copy link

JorisM commented Oct 25, 2021

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

  • the encoder (lib/encode-query-loader.js) works correctly, and returns the AST with the encoded fills.
  • if subsitute the const query with a hardcoded value, the svgs are transformed correctly

I then looked at this.resourceQuery in loader.js

  • with webpack 4: this.resourceQuery is set correctly to ?fill=#fff
  • with webpack 5: this.resourceQuery alway is set to ?fill= which then results in normalizedRules to be an emtpy array.

@JorisM
Copy link

JorisM commented Oct 25, 2021

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

JorisM added a commit to JorisM/svg-mixer that referenced this issue Oct 25, 2021
fix resourceQuery changes resulting in properties not being applied
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants