facebook / create-react-app

Set up a modern web app by running one command.

Home Page:https://create-react-app.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compilation error with react-scripts 4.0.0 ( Can't resolve file )

masbaehr opened this issue · comments

latest update of react-scripts to 4.0.0 from 3.4.4 causes a compilation problem.
With 3.4.4 it works, and the file exists

./src/styles/mycssfile.css
Error: Can't resolve '/images/module/filename.png' in 'D:\dev\workspace\xxxxxxxxx\src\styles'


npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xxxxxxxxxxxxxxx@1.0.0 build: `react-scripts build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xxxxxxxxxxxxx@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\xxxxxxxxxxxxxx\AppData\Roaming\npm-cache\_logs\2020-10-23T16_16_47_530Z-debug.log

Having a similar issue but with sass url() imports of images in the /public folder

What does the import line look like? What kind of file is it in?

I had the same url() issue as @efeichen and fixed it by moving images to src/.

@jrr background-image: url(/contact-clip.svg); it's in a sass file in /src/scss

I'd like to move the images to src/ since I believe the relative path from the sass file to the image is working (but can't do that for images in public because of the can't import from outside src restriction), but I'd prefer not to unless absolutely necessary (I have a fairly large public folder). Thanks for the tip though!

I have the same problem with SCSS and CSS files (images and fonts). In 3.x.x works but now it says it can't resolve the file in src.

I also have a problem when loading fonts from public folder. It did work in 3.x.x

I had the exact same issue, it started just today when I upgraded to 4.0.0

src: url(/fonts/josefin-sans-regular.ttf)

image

And it leads to the error:

Error: Can't resolve '../fonts/josefin-sans-regular.ttf' in '.\frontend\src\scss'

I had this error on a project that was using absolute imports. It seems like setting NODE_PATH=src/ in the .env file is no longer supported. I instead had to use a jsconfig.json as described here: https://code.visualstudio.com/docs/languages/jsconfig

{
  "compilerOptions": {
    "baseUrl": "src"
  },
  "include": ["src"]
}
commented

I'm also seeing this issue where we have an image in /public but it's not getting resolved when reference in css using url:

.background-image { background: url('/bg.jpg'); }

Error:

./src/styles/style.css (./node_modules/css-loader/dist/cjs.js??ref--4-oneOf-4-1!./node_modules/postcss-loader/src??postcss!./src/styles/style.css) Error: Can't resolve '/bg.jpg' in '/mnt/c/git/application/src/styles'

Can confirm this happens with url() calls in @font-face directives as well as per react-scripts@4.0.0. For instance:

@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: normal;
  font-display: swap;
  src: local('Nunito Bold'), local('Nunito-Bold'), url('/fonts/nunito.woff2') format('woff2');
}
./src/index.css (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-4-1!./node_modules/postcss-loader/src??postcss!./src/index.css)
Error: Can't resolve '/fonts/nunito.woff2' in '/Path/To/Project/src'

Edit: I dug into the changelog and I’m a little confused as to why it stopped working since css-loader and postcss-loader were not updated css-loader was in fact updated.

It looks like this is caused by the css-loader migration to v4: webpack-contrib/css-loader@bc19ddd#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L128.

Originally, a root-relative path like /foo/bar.ext would remain untouched, but as per css-loader@4 it becomes processed:

Screenshot 2020-10-27 at 10 48 15

Screenshot 2020-10-27 at 10 48 31

To be fair, there was a warning in v3.4.4
image

But this does not solve the style issues using url() referencing images from public folder

We are using another repo folder for the assets. I'm getting an error:

./src/components/HTMLPreview/HTMLPreview.module.scss (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-7-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--5-oneOf-7-3!./node_modules/sass-loader/dist/cjs.js??ref--5-oneOf-7-4!./src/components/HTMLPreview/HTMLPreview.module.scss)

Error: Can't resolve '../../assets/iphone.svg' in '.../src/components/HTMLPreview'

How can I disable this validation and use this path?
Worked in v3.4.4

this is crazy! no testing seriously? I broke a production app before deploying thank God!

you have not even mentioned this anywhere??

this is crazy! no testing seriously? I broke a production app before deploying thank God!

you have not even mentioned this anywhere??

@x5engine What? Who is "you"?

Edit:

The 👎 urges me to clarify that the question Who is "you"? could be replaced with Who has not even mentioned this anywhere?

this is crazy! no testing seriously? I broke a production app before deploying thank God!

Chill. Also, this is a major update. That implies breaking changes.

this is crazy! no testing seriously? I broke a production app before deploying thank God!

you have not even mentioned this anywhere??

@x5engine What? Who is "you"?

Who dis new phone?

I am the engine.

this is crazy! no testing seriously? I broke a production app before deploying thank God!

Chill. Also, this is a major update. That implies breaking changes.

Yeah man I was going nuts.

Hope this gets sorted out soon 🙂

running the same issue... waiting for clues

If you care to dive into the react-scripts webpack setup, you can pass in the option to disable url routing to css-loader. In node_modules/react-scripts/config/webpack.config.js on line 121 change

options: cssOptions,

to

options: {...cssOptions, url: false},

Of course this entails all the issues that come around with modifying the config inside of node_modules, but hopefully this might help in a long term fix for the change in css-loader resolving the urls.

Looking at css-loader it looks like they're not going to fix it webpack-contrib/css-loader#1136 (comment)

You would have to include /public to the resolve paths. I just moved my assets to /src as I didn't want to eject

For those used to patch-package, here's the patch based on @elylucas workaround

diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
index 80c6ac2..01de68e 100644
--- a/node_modules/react-scripts/config/webpack.config.js
+++ b/node_modules/react-scripts/config/webpack.config.js
@@ -117,7 +117,7 @@ module.exports = function (webpackEnv) {
       },
       {
         loader: require.resolve('css-loader'),
-        options: cssOptions,
+        options: {...cssOptions, url: false},
       },
       {
         // Options for PostCSS as we reference these options twice

Edit: Actually, that workaround only solves the issue in development (npm start), but build files are using a wrong import (they're being prefixed with ../ making it fail)

I had an issue loading fonts from within CSS. But thanks to @evilebottnawi pointing out how webpack/css-loader@4+ resolves URLs i was able to fix my issues:

/font/font.woff2 never was and never can be ./font/font.woff2, please read spec about URL resolving in CSS

I use rsuite as a UI framework. To override default icon font settings you can set a less variable @icon-font-path to suit your needs. I did that in a way which worked when using webpack/css-loader@3 but needed to be changed like displayed below to avoid issues when using webpack/css-loader@4.

/src/app/styles/rsuite/index.less:

-      @import '../../../../node_modules/rsuite/lib/styles/themes/default/core';
+      @import './node_modules/rsuite/lib/styles/themes/default/core';

-      @icon-font-path: '/fonts/rsuite-icon';
+      @icon-font-path: './fonts/rsuite-icon';

My icon font is located in /public/fonts/rsuite-icon.

Maybe this helps by getting the idea of how URLs are resolved.


Edit:

Forgot to mention how @icon-font-path is actually used:

@font-face {
  font-family: @font-family-icon;
  src: url('@{icon-font-path}/rsuite-icon-font.ttf') format('truetype'),
    url('@{icon-font-path}/rsuite-icon-font.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

Edit:

Oh my, what was i thinking... I wasn't aware of a faulty configuration because of working fallback mechanisms i didn't notice. I had to update my craco.config.js like this:

module.exports = function ({ env }) {
  return {
    style: {
      css: {
        loaderOptions: {
          url: false,
        },
      },
    },
    ...
  };
};

and had to roll back like this

+      @icon-font-path: '/fonts/rsuite-icon';
-      @icon-font-path: './fonts/rsuite-icon';

This way URLs in CSS won't be handled by webpack and you can use them like you would in regular CSS & HTML, if i got that straight.

If you do not rely on webpack handling URLs in CSS this could be an option for you.

I had to remove the . from @icon-font-path: './fonts/rsuite-icon'; because otherwise the file URL would depend on the current URL (CSS works at https://domain.tld but doesn't work at https://domain.tld/path).

We had the same issue when trying out CRA 4. Btw. this seems to effect a lot of people, it's been reported in multiple issues:
#9937
#9992
#10022

I have the same issue.
Upgraded to CRA4, try to run and got error:
Can't resolve './animations.scss'
where the line is:
@import url('./animations.scss');

Here's a fix using react-app-rewired for css files with absolute links. In config-override.js, do:

const getCssLoaders = config => {
  const loaderFilter = rule => rule.loader && rule.loader.includes('/css-loader')

  let loaders = config.module.rules.find(rule => Array.isArray(rule.oneOf)).oneOf

  loaders = loaders.reduce((ldrs, rule) => ldrs.concat(rule.use || []), [])

  return loaders.filter(loaderFilter)
}

/**
 * Overrides a create-react-app configuration for the given sources.
 *
 * @param src Source path of the create-react-app project.
 */
module.exports = (config, env) => {
  // Fix url('/images/....') being processed by css-loader 4 =/
  for (const loader of getCssLoaders(config)) {
    loader.options.url = url => url.startsWith('.')
  }
   return config
}

If you care to dive into the react-scripts webpack setup, you can pass in the option to disable url routing to css-loader. In node_modules/react-scripts/config/webpack.config.js on line 121 change

options: cssOptions,

to

options: {...cssOptions, url: false},

Of course this entails all the issues that come around with modifying the config inside of node_modules, but hopefully this might help in a long term fix for the change in css-loader resolving the urls.

Great 👯 It's worked.

Having the same problem with CRA 4.0.1: paths in css/url does not resolve and break the process

@font-face {
font-family: "percolate";
src: url("/icon/percolate.eot"); /* here is the error */
font-weight: normal;
font-style: normal;
}

the assets are in public folder

If you care to dive into the react-scripts webpack setup, you can pass in the option to disable url routing to css-loader. In node_modules/react-scripts/config/webpack.config.js on line 121 change

options: cssOptions,

to

options: {...cssOptions, url: false},

Of course this entails all the issues that come around with modifying the config inside of node_modules, but hopefully this might help in a long term fix for the change in css-loader resolving the urls.

It works, thanks!

Our product needs more nuanced resolution. Setting url: false will then prevent relative file paths from resolving. Best of both worlds may be adding conditional resolution, something like:

  // ...
  options: {
    ...cssOptions,
    url: url => !url.startsWith(/)
  },
  // ...

When compiled, /example.jpg will still be /example.jpg but ./local.jpg will be <dynamic_path>/local.<hash>.jpg.

my solution with react-app-rewired, in webpack function in config-overrides.js, paste in following lines:

// override css loader rules due to bug: https://github.com/facebook/create-react-app/issues/9870
    const cssLoaderRules = config.module.rules[1].oneOf.filter(rule => rule.use);
    cssLoaderRules.forEach(rule => {
      const cssLoader = rule.use[1];
      cssLoader.options.url = false;
    })
    process.stdout.write('**** overrided CRA webpack css loader rules **** \n')
    process.stdout.write(JSON.stringify(cssLoaderRules)+"\n");
    process.stdout.write('\n')

It just turn off url() resolving of static assets by css-loader.

I'm surprised that more people haven't realised that this is a major concern for SEO.

Lets say that you have a image file within the src folder, and you're using it within your CSS file like this -

.Profile {
text-align: center;
background-image: url("../../images/user/profile.png");
}

If this profile.png file is inside the src > images > user directory, then while creating a build with react-scripts, the URL generated for this file will be something like this -

https://{my-domain.com}/static/media/profile.{hash}.jpg

This {hash} value changes with every build. Therefore, if you use this in a static website, and if your website is crawled by google bot, you may see 404's reported in the google search console the next time you deploy, because Google can take several weeks before indexing your site again.

This is where an image in the public folder would have helped, because that URL will never change, and can safely remain indexed in search engines.

Does Google even index images from CSS backgrounds?

I ran into this when upgrading a large project to the latest react-scripts. All css url('/assets') imports break due to absolute path changes in css-loader. My workaround isn't ideal but it allows compilation without major refactors.

  1. Keep all your assets in /public/assets because any jsx needs eg. <img src="/assets/file.png" />
  2. Create a new directory /src/assets.
  3. Any time you are using css (or sass) url imports copy the file into the /src/assets folder
  4. Replace absolute paths with relative ones in the css import. Eg. replace url('/assets/file.png') with url('../../assets/file.png')

Please update webpack to the latest version (v4)

Hello, guys,
I've also faced this issue after updating to 4.0.0 (or actually 4.0.1).

As a workaround I use declaring background image right in JSX, like you know:
<div style={{background: 'url(/img/bg/image.jpg)'}}><div>

It works, because obviously css-loader has nothing to do with JSX files.

And it works for me, because code is arranged in a way where background can be changed depending on the section of application. In other words I use 1 component with several times with different images or maybe in different projects.

As for other projects, I'd like to join collective resentment. It seems to be strange to store images in src and I certainly don't have a teeny tiny intention to mess with webpack :-)

Does Google even index images from CSS backgrounds?

It does. Images show up in google image search results.

Also experiencing the same issue using react-scripts 4.0.1. The comments in webpack-contrib/css-loader#1136 are less than helpful. I have an image in <root>/public/assets I am trying to reference in the css as

background-image: url(/assets/image.jpg);

and am getting

./src/App.css (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-4-1!./node_modules/postcss-loader/src??postcss!./src/App.css)
Error: Can't resolve '/assets/image.jpg' in '<root>/src'

The options as I see it are:

  1. Move the image into src and avoid the css-loader altogether. Would prefer not to as means changing the logical structure of my project just to workaround a problem with tooling.
  2. Use root relative urls in css ie /public/assets/image.jpg. Fails with the error message
./src/App.css (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-4-1!./node_modules/postcss-loader/src??postcss!./src/App.css)
Module not found: You attempted to import ../public/assets/image.jpg which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
  1. Eject and switch off url checking in css-loader. I lose automatic updates to react-scripts (including potentially a fix to this problem), and kinda negates the point of the changes in css-loader in the first place.
  2. Use react-app-rewired to override and do the option 3 above without ejecting as described here and here. Probably the best option, but again negates the point of the css-loader changes and means adding a layer of overrides over something that should just work.

Is there any improvement on this, and what would be needed to be changed in create-react-app/react-scripts to get url() to just work with the <root>\public directory in react apps?

@donal-s

Or option 5, see @atiastudio comment. Change any css url imports to jsx

I am no expert but I have an easy fix to this css image issue. I used react style attribute (inline) for the image path. and did the rest of the styling in css. That way you can still support styling like background-attachment: fixed and so forth

I'd suggest there is a difference between fix and workaround. A fix would be the tooling not inhibiting the dev from using the existing css url() feature inside a css file (as opposed to inline style attributes), and being able to reference assets where many (not all of course) would think is the most logical place (the public folder).
The workarounds all share one common feature - ways to switch off or bypass the new url() checks from css-loader, which is not ideal, and also all have some level of hack around what a dev would normally do here to get an image/font/whatever referenced from css.
Currently, all we have are workarounds, so I guess that's what we make do with for now :)

As developer of css-loader, I want to say that css-loader supports /images/image.png in url, CRA should add src to resolver.roots (and using /images/image.png will be resolved as /src/images/image.png, it is default behavior for webpack@5)

Anyway we can implement:

div {
  /** webpackIgnore **/
  background: url(/images/image.png);
}

and don't touch this url, if somebody want this, feel free to open a new issue in css-loader

As developer of css-loader, I want to say that css-loader supports /images/image.png in url, CRA should add src to resolver.roots (and using /images/image.png will be resolved as /src/images/image.png, it is default behavior for webpack@5)

Would adding public to resolver.roots mean that adding url(/assets/image.png) correctly resolves to <rootdir>/public/assets/image.png? I think that's what we want.

@donal-s Yes, just add public to resolver.roots

I had a scan of webpack, css-loader, and react-scripts. I'm still not clear on what exactly needs to be changed where in react-scripts to fix this issue. Could someone more familiar with these projects take a look at applying @alexander-akait 's suggestion please?

To the above list of workarounds, I can add the following pragmatic one if you are facing this error while trying to load local fonts from the public folder:

Add (for the time being) the style in your index.html.

<html>
  <head>
      <style>
      @font-face {
        font-family: "Open Sans";
        font-style: normal;
        font-weight: 300;
        font-display: swap;
        src: url("/assets/fonts/open-sans-v17-latin-300.eot"); /* IE9 Compat Modes */
        src: local("Open Sans Light"), local("OpenSans-Light"), url("/assets/fonts/open-sans-v17-latin-300.eot?#iefix") format("embedded-opentype"),
          /* IE6-IE8 */ url("/assets/fonts/open-sans-v17-latin-300.woff2") format("woff2"),
          /* Super Modern Browsers */ url("/assets/fonts/open-sans-v17-latin-300.woff") format("woff"),
          /* Modern Browsers */ url("/assets/fonts/open-sans-v17-latin-300.ttf") format("truetype"),
          /* Safari, Android, iOS */ url("/assets/fonts/open-sans-v17-latin-300.svg#OpenSans") format("svg"); /* Legacy iOS */
      }
      
      ...

I moved svg, png, jpg and font files from /public to /src and referenced them in jsx/scss/css files as recommended here

I have no need for the public folder right now so I am fine with this solution.

// edit : ok still issues loading images from a list of paths

commented

Unfortunately nothing has worked for me so I moved the images directory inside the src and wherever I was using the image I had to import the images one by one by doing the following:

import img2 from '../images/img-2.jpg'
import img9 from '../images/img-9.jpg'
...
<CardItem src={img2} ... />
<CardItem src={img9} ... />
...
and so on.

I am very new to React, I'm learning new things everyday as I go so I'm not 100% sure if this is a proper solution, but this worked for me. I'd appreciate anybody's feedback or thoughts on this solution.

Hello, guys,
I've also faced this issue after updating to 4.0.0 (or actually 4.0.1).

As a workaround I use declaring background image right in JSX, like you know:
<div style={{background: 'url(/img/bg/image.jpg)'}}><div>

It works, because obviously css-loader has nothing to do with JSX files.

And it works for me, because code is arranged in a way where background can be changed depending on the section of application. In other words I use 1 component with several times with different images or maybe in different projects.

As for other projects, I'd like to join collective resentment. It seems to be strange to store images in src and I certainly don't have a teeny tiny intention to mess with webpack :-)

Thank you! Finally something workable. You can also add a style section to the index.html which is guaranteed to bypass all the transpilation.

This is very annoying issue

Just note, the latest version of css-loader supports /* webpackIgnore: true */, i.e. you can write

a {
  /* webpackIgnore: true */
  background: url('/my/strange/path/to/image.png');
}

Here's a fix using react-app-rewired for css files with absolute links. In config-override.js, do:

const getCssLoaders = config => {
  const loaderFilter = rule => rule.loader && rule.loader.includes('/css-loader')

  let loaders = config.module.rules.find(rule => Array.isArray(rule.oneOf)).oneOf

  loaders = loaders.reduce((ldrs, rule) => ldrs.concat(rule.use || []), [])

  return loaders.filter(loaderFilter)
}

/**
 * Overrides a create-react-app configuration for the given sources.
 *
 * @param src Source path of the create-react-app project.
 */
module.exports = (config, env) => {
  // Fix url('/images/....') being processed by css-loader 4 =/
  for (const loader of getCssLoaders(config)) {
    loader.options.url = url => url.startsWith('.')
  }
   return config
}

Works like a charm.
Just a detail: the correct filename is config-overrides.js, i.e. with s at the end.

I followed @Gatix comment:

I just moved my assets to /src

Moving assets (at least those read by css-loader) from public to src is not a big deal and is the "recommended way" of Adding Images, Fonts, and Files as stated in the CRA documentation: https://create-react-app.dev/docs/adding-images-fonts-and-files

For example, when you import font files from src, they are seemlessly copied in the production build:

Capture d’écran 2021-04-04 à 11 37 23

Capture d’écran 2021-04-04 à 11 36 10

Note that the hash part (e.g. 504a4f4a), included in the built files name, seems to be based on the file content, so it shouldn't break assets caching after each build deployment.

Looks like rearranging the structure of the project is the recommended way to go then. The separation of content between src and public is a bit confusing then (to me) - why have a public folder at all as part of CRA if its criteria is any static assets unless you reference them in the code. I get that CRA is opinionated, and that's fine - this particular opinion can get confusing...

(In the meantime I've converted the projects to webpack 5 anyway ;) )

The separation of content between src and public

The public folder was supposed to serve files during development which

  1. Are served from a separate server during the production mode
  2. Should not be included in a production build

Is this not the case anymore?

If anyone wishes to keep files in public folder (as for various reasons) see my answer on SO how to make it work with CRA 4.0.x and craco

https://stackoverflow.com/questions/65058233/cant-resolve-scss-file-after-upgrade-to-create-react-app-4-0-1/68020124#68020124

For those used to patch-package, here's the patch based on @elylucas workaround

diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
index 80c6ac2..01de68e 100644
--- a/node_modules/react-scripts/config/webpack.config.js
+++ b/node_modules/react-scripts/config/webpack.config.js
@@ -117,7 +117,7 @@ module.exports = function (webpackEnv) {
       },
       {
         loader: require.resolve('css-loader'),
-        options: cssOptions,
+        options: {...cssOptions, url: false},
       },
       {
         // Options for PostCSS as we reference these options twice

Edit: Actually, that workaround only solves the issue in development (npm start), but build files are using a wrong import (they're being prefixed with ../ making it fail)

Worked for my finally after 3 days long struggle. Thanks

@mghazanfar this will disable all url resolving.

We wanted only to not resolve urls from /resources url so the following worked for us

...
options: {...cssOptions, url: url => !url.startsWith("/.resources")},
....

That way other urls that you use inside your scss files in components will still resolve.

./src/components/Home/Header/Header.css (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-4-1!./node_modules/postcss-loader/src??postcss!./src/components/Home/Header/Header.css)
Error: Can't resolve '/images/header-bg.png' in 'C:\Users\nihal\Desktop\PlayGround\TRANSFORM\Creative-Agency\src\components\Home\Header'

I GOT THE SAME ERROR. I CAN'T ACCESS public FOLDER IMAGES FROM ANY .css FILE.
I USE THAT IMAGE IN ::before CSS SELECTOR FOR BACKGROUND IMAGE;

having this issue with "react-scripts": "4.0.3" (not ejected), any idea if the issue is on the roadmap?

Thanks to chriswininger. I could resolve my issue following his advice.

I changed the syntax of quotes from url('/images/img-2.jpg') to 'url(/images/img-2.jpg)' in my App.css file

I wanted to load a background image from Tailwind, but I got the error "./src/index.css Error: Can't resolve '/img...", CRA comes with "@craco/craco": "^6.4.0", and "react-scripts": "4.0.3", for these versions, it doesn't work to load the image with the relative path. Performing @ejose19's workaround works but it is not ideal. My solution was to downgrade the versions of "@craco/craco":"^5.6.0" and "react-scripts":"^3.3.0-next.38" and it worked without problems. What a way to waste time...

For those used to patch-package, here's the patch based on @elylucas workaround

diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
index 80c6ac2..01de68e 100644
--- a/node_modules/react-scripts/config/webpack.config.js
+++ b/node_modules/react-scripts/config/webpack.config.js
@@ -117,7 +117,7 @@ module.exports = function (webpackEnv) {
       },
       {
         loader: require.resolve('css-loader'),
-        options: cssOptions,
+        options: {...cssOptions, url: false},
       },
       {
         // Options for PostCSS as we reference these options twice

Edit: Actually, that workaround only solves the issue in development (npm start), but build files are using a wrong import (they're being prefixed with ../ making it fail)

Worked for my finally after 3 days long struggle. Thanks

This works localy but if you deploy your app with netlify for instance it would crash because the node_modules is no shipped to the server before builds.
What finaly worked for me was setting url for loaderOptions to false in craco.config.js as @iwan-uschka mentionned.
Like so
module.exports = { style: { postcss: { plugins: [ require('tailwindcss'), require('autoprefixer'), ], }, css: { loaderOptions: { url: false, } } }, }
#9870 (comment)

I can't believe this is still an issue. Setting url: false will simply disable resolving anything from the public directory.

This will solve the issue given the following folder structure:

project
  --src
      --styles
        --main.scss // imports images or svgs from the public/resources dir
  --public
    --resources
      --images
        - my-awesome-logo.svg
  1. Install patch-package as a devDependency: yarn add -D patch-package
  2. In your node_modules folder navigate to /node_modules/react-scripts/config/webpack.config.js and find line
    options: cssOptions and replace it with
    options: {...cssOptions, url: url => !url.startsWith("/resources")},
    (This will ensure that any import which starts with /resources will get resolved from the public directory.)
  3. Navigate back to the project root and run yarn patch-package react-scripts. This will create a new directory called patches which should contain a git-patch for the react-scripts package.
  4. In your package.json add the following to the scripts block:
...
"scripts": {
  ...
  "postinstall": "patch-package"
  ...
  }
...

This will run the patches after every install. You can (and should) commit these files to the repository.

As developer of css-loader, I want to say that css-loader supports /images/image.png in url, CRA should add src to resolver.roots (and using /images/image.png will be resolved as /src/images/image.png, it is default behavior for webpack@5)

This worked for me. So /path-to-file in the url() will be resolved as /src/path-to-file

react-scripts 5.0.0 was released and this issue was not addressed.

https://github.com/facebook/create-react-app/releases/tag/v5.0.0

Some excerpts from the official docs related with this issue:

Using the Public Folder | Create React App

With webpack, using static assets like images and fonts works similarly to CSS.

You can import a file right in a JavaScript module. This tells webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the src attribute of an image or the href of a link to a PDF.

Adding Images, Fonts, and Files | Create React App

Normally we recommend importing stylesheets, images, and fonts from JavaScript. The public folder is useful as a workaround for a number of less common cases:

I used the "patch" approach in some projects for a while but finally switched to the relative path approach (by moving images into src/ directory).

@gh640

I used the "patch" approach in some projects for a while but finally switched to the relative path approach (by moving images into src/ directory).

Doesn't this mean that they'll be included in the production build? My understanding was that the public folder served assets which

a) are available in prod environments and thus don't need to be included in the dev build.
b) are required during the development process

@polaroidkidd

Doesn't this mean that they'll be included in the production build? My understanding was that the public folder served assets which

a) are available in prod environments and thus don't need to be included in the dev build.
b) are required during the development process

Thank you for your comment. Personally speaking, I don't think it's an intended use case but I'm not sure, it's just my understanding...

Moving assets (at least those read by css-loader) from public to src is not a big deal and is the "recommended way" of Adding Images, Fonts, and Files as stated in the CRA documentation: https://create-react-app.dev/docs/adding-images-fonts-and-files

Just hit this issue today, when i upgraded react-scripts in my app. I am moving forward with this one. I think this is the best way to go now, because adding more and more configurations ( which will be fixed in the near future ) would not be the best idea.
Thanks man.

I followed @Gatix comment:

I just moved my assets to /src

Moving assets (at least those read by css-loader) from public to src is not a big deal and is the "recommended way" of Adding Images, Fonts, and Files as stated in the CRA documentation: https://create-react-app.dev/docs/adding-images-fonts-and-files

For example, when you import font files from src, they are seemlessly copied in the production build:

Capture d’écran 2021-04-04 à 11 37 23 Capture d’écran 2021-04-04 à 11 36 10

Note that the hash part (e.g. 504a4f4a), included in the built files name, seems to be based on the file content, so it shouldn't break assets caching after each build deployment.

This solution solved the issue for me. I think this is the best way.

This is still an issue for me

@alihesari 's solution worked perfectly for me.