0

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!');
  • file-loader also has additional options, outputPath and publicPath. You should be interested in them. Of course, a different path is for the dev version and different for the prod ;) – Grzegorz T. Jan 10 '20 at 11:06
  • Thank you! I had those settings, but removed them as they didn't have any effect, I believe my settings for those are the same as the defaults, since my `publicPath` is the same as `output.publicPath` and is had `outputPath: 'image'` but removed that for simplicity's sake. – Dimitri Dhuyvetter Jan 10 '20 at 11:29
  • I prepared an example with a photo in the background [background-image](https://github.com/tomik23/webpack-babel-corejs/tree/background-image) – Grzegorz T. Jan 10 '20 at 12:11
  • Thank you! Having a look at it now. Will see if I can find how to fix my issue from this working example. – Dimitri Dhuyvetter Jan 10 '20 at 14:15

1 Answers1

1

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.