1

Resolve-url-loader is not resolving images/fonts in my css files. My folder structure is like this:

src 
   public
      images
           -banner-bg.jpg
      stylesheets
         css
           -basic.css with background: url(../../images/banner-bg.jpg)
         scss
           -main.scss with @import "../css/basic.css";

The output folders:

dist
  public
     images
           -banner-bg.jpg
     stylesheets
           -main-output.css

The images & fonts diplay ok in dev server and are correctly copied in production. The main-output.css - when examined - shows

background:url(public/images/banner-bg.jpg

instead of the expected

background:url(../images/banner-bg.jpg)

And the browser console shows the error:

GET file:///home/ustrd/Documents/myproject12/dist/ public/stylesheets/public/images/ banner-bg.jpg net::ERR_FILE_NOT_FOUND

plugins: [
   new MiniCssExtractPlugin({
     filename: path.join("public", "stylesheets", "[name].css")
   })
 ],
 module: {
   rules: [
     {
       test: /\.(css|scss)$/,
       use: [
         MiniCssExtractPlugin.loader, 
         {
           loader: "css-loader",
           options: {
             sourceMap: true,
             importLoaders: 2
           }
         },
         {
           loader: "postcss-loader",
           options: {
             ident: "postcss",
             plugins: () => [new PostcssPresetEnv()]
           }
         },
         {
           loader: "resolve-url-loader",
           options: { sourceMap: true }
         },
         { loader: "sass-loader", options: { sourceMap: true } } 
       ]
     },

Any ideas how to fix that?

enhancedJack
  • 265
  • 1
  • 6
  • 15

1 Answers1

0

I guess that resolve-url-loader doesn't know about the location of your final main-output.css and expects it to be at the roof of the dist. You can try to use a custom join function to fix the paths:

{
  loader: "resolve-url-loader",
  options: {
    sourceMap: true,
    join: (uri, base) => path.join('../..', base, uri);
  }
},

This should output something like this:

background:url(../../public/images/banner-bg.jpg)

Haven't tested it though. Check how-it-works for some details. Also take a look at css-loader url setting.

It might be easier to change the location of main-output.css:

new MiniCssExtractPlugin({
     filename: "[name].css"
})
UjinT34
  • 4,784
  • 1
  • 12
  • 26
  • 1
    1. join: (uri, base) => path.join('../..', base, uri); results in an error: **TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type object** I read the doc for resolve-url-loader but I don't understand it. 2. Putting min-output.css in the root of the output folder **DOES work** but it is an ugly solution unless I add a script to put the file back in the stylesheets folder after Webpack has completed its job. – enhancedJack Jun 18 '19 at 09:40
  • 3. This **css-loader** solution has absolutely no impact on the image's url: `loader: "css-loader", options: { url: (url, resourcePath) => { if (url.includes("banner-bg.png")) { return false; } return true; }, },` – enhancedJack Jun 18 '19 at 09:43