Webpack-5 - Webpack tries to resolve root-relative paths to images in scss (or css) and fails
Asked Answered
A

1

8

I'm getting this error after upgrading to Webpack-5:

Error: Can't resolve '/path/to/image.jpg' in '/app/path/to/module/module'

The issue is with images used for css backgrounds where the files aren't stored in the repository, and are not available at build-time. (Why it's this way is a story for another time.)

The issue:

In my scss file:

background-image: url(/path/to/image.jpg);

In Webpack-4, it was left as-is, and just worked.

Webpack-5 tries processing the image and fails with the error above.

This didn't work:

Adding quotes to the path...

background-image: url("/path/to/image.jpg");

I've tried Webpacks magic comments...

/* webpackIgnore: true */
background-image: url(/path/to/image.jpg)

... but it didn't work (maybe they were getting stripped too early? - This seems to be the case as is evidenced by the dev build working in my create-react-app example)

webpack.IgnorePlugin πŸ‘Ž

I also tried some of the edge-case tips from here. But i think that comes in too late because Webpack already assumes that the file exists.

This worked but...

What does work, is including the absolute path to the asset:

background-image: url(https://www.example.com/path/to/image.jpg);

But that creates it's own set of problems.

Update:

I reproduced the issue in this repo:

The Webpack magic comments work for the development build, but not for the production build.

~/webpack-test$ npm run build

> [email protected] build
> node scripts/build.js

Creating an optimized production build...
Failed to compile.

Module not found: Error: Can't resolve '/mypics/pom.jpg' in '/home/nodejs/webpack-test/src'
Almond answered 24/2, 2022 at 15:20 Comment(7)
Are you able to provide your webpack config here or a link to it in a pastebin? That would probably help get this debugged – Deonnadeonne
It's insanely complex, but want to reproduce it in an example project. Do you know of an example bootstrap project? – Almond
Maybe I'll just eject from create-react-app to get a boilerplate. – Almond
That would work! – Deonnadeonne
@Deonnadeonne I did it github.com/dovidweisz/webpack-test – Almond
Bravo! Well done – Deonnadeonne
Filled a bug reporr too: github.com/webpack/webpack/issues/15499 – Almond
A
8

It turns out that the css-loader has configuration options just for this under options.url!

Thank you Alexander Akait from the Webpack team for answering my question here.

It has the option to pass an object that contains a filter() predicate function that should determine whether a path should be processed:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "css-loader",
        options: {
          url: {
            filter: (url, _resourcePath) => {
              // Disable processing for root-relative urls under /images
              return !/^\/images\//.test(url)

              // This would disable processing for all root-relative urls:
              // return !/^\//.test(url);
            },
          },
        },
      },
    ],
  },
};

Here is the commit I used to fix this issue in the repo mentioned in the question: https://github.com/dovidweisz/webpack-test/commit/a9e4cfc4ae0a5a8475ddd2cc114a8650846db421

You can also disable ALL url-handling by simply passing false to options.url:

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "css-loader",
        options: {
          url: false,
        },
      },
    ],
  },
};
Almond answered 10/3, 2022 at 18:46 Comment(1)
This fixed my problem right up. I added it to my .css and .scss rules. I get no more randomly named images in my dist folder, and the image paths are left untouched. They are absolute and remain so, in the output. This helps a lot, since I inline (= load into memory) them with Web Optimizer. This doesn't work with relative paths, since the path of the css changes when you inline it in a page on a different path as the source location of the inlined css. But since they stay absolute, now it does work. Tnx! – Weiland

© 2022 - 2024 β€” McMap. All rights reserved.