Webpack 4 with sass-loader & resolve-url-loader - Image paths not being found

It turns out all I needed was file-loader to do what I wanted.

When an image (matching my specified file extensions) is encountered by any of the css/sass/style loaders, its processed through file-loader, which both copies it to the output directory specified with the naming format specified and returns the name for the sass loader to use as the file name.

rules: [
  {
    test: /\.(png|jpg|gif|svg)$/,
    exclude: [
      path.resolve(__dirname, './node_modules'),
    ],
    use: {
      loader: 'file-loader',
      options: {
        name: '[path][name]-[hash].[ext]',
        outputPath: '../',
        publicPath: '/dist',
      },
    },
  },
  {
    test: /\.svg$/,
    include: [
      path.resolve(__dirname, './node_modules'),
    ],
    use: {
      loader: 'svg-inline-loader',
      options: {
        name: '[name]-[hash].[ext]',
      },
    },
  },
  { test: /\/src\/js\/(?:.*)\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] },
  {
    test: [/\.scss$/, /\.sass$/],
    use: [
      MiniCssExtractPlugin.loader,
      {
        loader: 'css-loader',
        options: {
          sourceMap: true,
          root: path.resolve(__dirname),
        },
      },
      {
        loader: 'postcss-loader',
        options: {
          ident: 'postcss',
          plugins: () => [
            autoprefixer({
              'browsers': ['last 2 versions', 'ie >= 10'],
            }),
          ],
          sourceMap: true,
        },
      },
      {
        loader: 'sass-loader',
        options: {
          outputStyle: 'compressed',
          sourceMap: true,
          includePaths: [
            './src/scss',
          ],
        },
      },
    ],
  },
  {
    test: /\.html$/,
    use: [
      {
        loader: 'html-loader',
        options: {
          root: path.resolve(__dirname),
        },
      },
    ],
  },
  {
    test: [
      /\/bundles\/(?:.*)\.js$/,
    ],
    use: {
      loader: 'babel-loader',
    },
  },
];

Actually resolve-url-loader is still needed sometimes... it depends if you want to be able to resolve url() calls from files imported inside the sass compilation. Without it urls would be broken in this case.

But if you don't use multi-file scss build (for example if each component has only 1 scss file local to it without calling shared library scss code or partials of some some sort) - then you don't need resolve-url-loader.

Of course you will still need url-loader (wraps file-loder with inlining abilities) or file-loader (for straight copying of assets to dist folder)

resolve-url-loader works by re-working original files from the sourcemap emitted by sass and sass-loader does have an issue with sourcemaps when working with the dart-sass implementaion. In this case sourcemap sources would mistakenly be stdin inplace of the filename see issue 671 and fix that came in PR 681

this is still unreleased fix as of today (July 2019) , the only option is to work with node-sass or use unreleased sass-loader