title: Webpack: css-loader not resolving url
body: <p>I am getting the below error when trying to use an image (background-image: url('path_to_image')) in my sass file under src directory. However, I am able to call the same file from index.js. I am not sure what is missing in my Webpack config.</p>
  
  <p>Error</p>
  
  <p>ERROR in ./src/sass/main.scss (./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/sass/main.scss) Module not found: Error: Can't resolve '../../img/hero-small.jpg'</p>
  
  <p>Folder structure</p>
  
  <pre><code>dist
    js
    public
       css
       images
  
  src
    img
    js
    sass
    index.js
  </code></pre>
  
  <p>Code where her-small.jpg is being called from</p>
  
  <p>source directory structure in closer detail:</p>
  
  <pre><code>img
  sass
    components
       header.scss
  </code></pre>
  
  <p>within the header.scss, I am calling   </p>
  
  <pre><code>background-image: url("../../img/hero-small.jpg");
  </code></pre>
  
  <p>Also, the output build css is showing the same path</p>
  
  <pre><code>background-image: url("../../img/hero-small.jpg");
  </code></pre>
  
  <p>package.json</p>
  
  <pre><code>  "devDependencies": {
      "babel-core": "^6.26.3",
      "babel-loader": "^7.1.5",
      "babel-preset-env": "^1.7.0",
      "babel-preset-es2015": "^6.24.1",
      "css-loader": "^1.0.0",
      "extract-text-webpack-plugin": "^4.0.0-beta.0",
      "file-loader": "^1.1.11",
      "sass-loader": "^7.0.3",
      "style-loader": "^0.21.0",
      "url-loader": "^1.0.1",
      "webpack": "^4.16.3",
      "webpack-cli": "^3.1.0",
      "webpack-dev-server": "^3.1.5"
    }
  </code></pre>
  
  <p>webpack.config.js</p>
  
  <pre><code>const path = require('path');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const ExtractTextPlugin = require('extract-text-webpack-plugin');
  
  module.exports = {
      entry: ['babel-polyfill', './src/js/index.js'],
      output: {
          path: path.resolve(__dirname, 'dist'),
          filename: 'js/bundle.js'
      },
      devServer: {
          contentBase: './dist'
      },
      plugins: [
          new HtmlWebpackPlugin({
              filename: 'index.html',
              template: './src/index.html'
          }),
          new ExtractTextPlugin('./public/css/main.css')
      ],
      module: {
          rules: [{
                  test:/\.js$/,
                  exclude: /node_modules/,
                  use:[{
                  loader: "babel-loader",
                  query: {presets:['es2015']}
                  }]
          }, {
                  test:/\.scss$/,
                  exclude: /node_modules/,
                  use: ExtractTextPlugin.extract({fallback:'style-loader',use:['css-loader','sass-loader']})
              },
              {
                  test:/\.(png|svg|jp(e*)g|gif)$/,
                  exclude:/node_modules/,
                  use:[{
                      loader: "file-loader",
                      options: {
                          name:'[name].[ext]',
                          outputPath:'./public/images'
                      }
                  }]
              }
          ]
      }
  };
  </code></pre>
  
  <p>UPDATE</p>
  
  <p>Based on this post, I have included one more loader:resolve-url-loader and set the options of css-loader for url to false.</p>
  
  <p>use: ExtractTextPlugin.extract({fallback:'style-loader',use:[{loader:'css-loader',options:{url:false}},'resolve-url-loader','sass-loader']})
  upon further research, I found the issues described on sass-loader github page:</p>
  
  <p>Since Sass/libsass does not provide url rewriting, all linked assets must be relative to the output. If you're just generating CSS without passing it to the css-loader, it must be relative to your web root. If you pass the generated CSS on to the css-loader, all urls must be relative to the entry-file (e.g. main.scss). More likely you will be disrupted by this second issue. It is natural to expect relative references to be resolved against the .scss file in which they are specified (like in regular .css files). Thankfully there are a two solutions to this problem: Add the missing url rewriting using the resolve-url-loader. Place it before the sass-loader in the loader chain. Library authors usually provide a variable to modify the asset path. bootstrap-sass for example has an $icon-font-path.</p>
  
  <p>use: ExtractTextPlugin.extract({fallback:'style-loader',use:[{loader:'css-loader',options:{url:false}},'resolve-url-loader','sass-loader']})
  After adding the above changes, build passes but the final url in my output dist folder is the same as the path I provided in the source folder (../../img/hero.jpg) which is resulting in a bad path.</p>
  
  <p>As a temporary solution:</p>
  
  <p>I have imported the images to my index.js file and let the file-loader load the images from my src directory to the dist/public/images directory.
  I referred the images in main.sass from dist/public/images hoping it will be available.
  Although it was not a fool proof solution, I hope that there's already a much easier solution that I am not aware of. Any help on this is much appreciated.</p>