webpackwebpack-dev-servermini-css-extract-plugin

WebPack: Background image not loading


Trying to load a CSS background image, defined in SCSS, and serving via WebPack devServer.

The background image defined in SCSS is picked up by WebPack, but it doesn't show on the page.

I have tried setting publicPath option in MiniCssExtractPlugin.loader and looked at all the answers I could find related to this problem, but haven't been able to get this to work.

Update: Also tried setting publicPath option in file-loader. According to the documentation this defaults to the output publicPath, which is the same in my case.

Update: When using an absolute path in SCSS it compiles to CSS as that exact path, but that isn't going to work as local dev and staging and prod all have different paths.

Relevant part of the output when running webpack-dev-server:

Child mini-css-extract-plugin node_modules/css-loader/index.js??ref--5-1!node_modules/sass-loader/dist/cjs.js??ref--5-2!index.scss:
                     Asset      Size  Chunks             Chunk Names
    pages/index/404@2x.png  29.2 KiB          [emitted]  

index.scss:

body {
  background: url("./pages/index/404@2x.png");
}

CSS output:

body {
    background: url([object Module]);
}

My WebPack config:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const path = require('path');
const outputDir = 'dist/website';
const publicPath = '/web/website/';

module.exports = {
  mode: 'development',
  devtool: 'source-map',
  entry: './index.ts',
  output: {
    path: path.resolve(__dirname, outputDir),
    publicPath: publicPath,
    filename: 'bundle.js',
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: ['ts-loader'],
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
            options: {
              sourcemap: true,
            },
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg|webp)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]',
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      path: path.resolve(__dirname, outputDir),
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
    new CleanWebpackPlugin([outputDir]),
  ],
  devServer: {
    contentBase: path.join(__dirname, outputDir),
    publicPath: publicPath,
    port: 9009,
    proxy: {
      '/': 'http://127.0.0.1:5000/',
    },
  },
};

index.ts:

import './index.scss';

console.log('WebPack is working!');

Solution

  • I have figured out the issue: css-loader was on version 1.0.0. Probab ly because it was installed a long time ago.

    Upgrading to the latest version of css-loader with npm install css-loader@latest --save-dev solved the issue.