css-loader generates urls with "auto"-prefix

Viewed 603

I have a setup where I use webpack to compile a css-file that has a url-link to a png image. Both, css-file and png are written to the output folder using hashed names. I use css-loader, extract-loader and file-loader to achieve this.

The whole setup worked just fine with webpack v4 and css-loader v3. Now I'm trying to migrate to webpack v5 and css-loader v5. With that the url-link in the generated css is wrong: It has an auto-prefix, e.g.

  • The generated png: logo.9941b604ef38475a0267fbba30e5b505.png
  • The url in the css: url(autologo.9941b604ef38475a0267fbba30e5b505.png)

Is this behavior intended or is this a bug?

The versions I use:
webpack: 5.38.1
css-loader: 5.2.6
file-loader: 6.2.0
extract-loader: 5.1.0

My webpack.config.js

const path = require('path');
const distDir = path.resolve(__dirname, 'dist');

module.exports =
{
    experiments:
    {
        asset: false
    },
    entry:
    {
        style: './src/style.js'
    },

    output:
    {
        filename: '[name].bundle.[contenthash].js',
        path: distDir,
    },

    module:
    {
        rules:
        [
            {
                resource: /\.css$/,
                use:
                [
                    {
                        loader: 'file-loader',
                        options:
                        {
                            name: '[name].[hash].css'
                        }
                    },
                    {
                        loader: 'extract-loader'
                    },
                    {
                        loader: 'css-loader'
                    }
                ],
            },

            {
                test: /\.png$/,
                use: {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[hash].[ext]'
                    }
                }
            }
        ]
    }
};

The style.js is just a dummy entry point where I simply import my css file.

Thanks for any feedback.

2 Answers

Option output.publicPath has default value 'auto' and I think the file-loader (in png's rule) can't interpret it right. In this case, one of the following values may be appropriate:

  • '' - for relative URLs, url(logo.<hash>.png)
  • '/' - for absolute URLs, url(/logo.<hash>.png)
// webpack.config.js
{
  ....
  output: {
    publicPath: '',
    ....
  },
  ....

Btw, Webpack 5 introduces a new way to handle assets, but I haven't been able to get it work with extract-loader, unfortunately (so I can't advice on that).

At least I found a workaround for this strange behavior:

Instead of using extract-loader and file-loader I now use the MiniCssExtractPlugin. With webpack v5 the file-loader is marked as deprecated anyway.

I also gave the new assets module a try (as suggested by the webpack docs) but couldn't get it to work in my scenario.

A drawback of this approach is that I need to define an entry point in webpack.config.js for each css-file I want to process as the MiniCssExtractPlugin generates a css-file for each entry point. Before I used a js-file as dummy entry point where I simply imported all css-files that needed processing.

Related