Webpack - background images not loading

There is currently a bug when using sourceMap with css-loader. Removing sourceMap from your css loader should fix it.

"module": {
    "loaders": [
        {
            "test": /\.scss$/,
            "loaders": ["style", "css", "sass?sourceMap"]
        },
        { 
            test: /\.jpg$/, 
            loader: "file-loader" 
        }
    ]
}

Issue is related to: https://github.com/webpack/css-loader/issues/296


It seems like browsers aren't fond of relative paths to background images on the body tag. (see also CSS Background image not loading and css background-image not working properly)

Changing the code slightly seemed to do the trick:

  • change the URL to an absolute URL: background-image: url(http://localhost:8080/5a09e4424f2ccffb6a33915700f5cb12.jpg). This is hardly ideal.
  • add a class to body, and change the styles to reference this class:
<body class="foo">

.foo {
    background-image: url('../img/test.jpg');
}

Neither of these solve the real question, but do get you unstuck.


After several hours around this, I just simply downgraded css-loader

npm install [email protected]

After struggling with this problem for a day, I finally figured out how to rewrite urls within css using postcss

webpack.config.js

const _ = require('lodash');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const argv = {
    verbose:    _.includes(process.argv, '-v') || _.includes(process.argv, '--verbose'),
    json:       _.includes(process.argv, '--json'),
    production: _.includes(process.argv, '--production'),
};
module.exports = {
    cache:   true,
    devtool: argv.production ? "source-maps" : "eval",
    output: {
        path: 'public/build',
        filename: '[name].js',
        publicPath: "/build/",
        pathinfo: true // use with devtool: "eval",
    },
    resolve: {
        modulesDirectories: ['node_modules'],
        extensions: ['', '.js', '.jsx']
    },
    module: {
        loaders: [
            {
                test: /\.less$/,
                loader: argv.production
                    ? ExtractTextPlugin.extract('style-loader?sourceMap=1', [
                        'css-loader?sourceMap=1&importLoaders=1',
                        'postcss-loader?sourceMap=1',
                        'less-loader?sourceMap=1'
                    ]) : [
                        'style-loader?sourceMap=1',
                        'css-loader?sourceMap=1&importLoaders=1',
                        'postcss-loader?sourceMap=1',
                        'less-loader?sourceMap=1'
                    ].join('!')
            },
            {
                test: /\.css$/,
                loader: argv.production
                    ? ExtractTextPlugin.extract('style-loader?sourceMap=1', [
                        'css-loader?sourceMap=1&importLoaders=1',
                        'postcss-loader?sourceMap=1',
                    ]) : [
                        'style-loader?sourceMap=1',
                        'css-loader?sourceMap=1&importLoaders=1',
                        'postcss-loader?sourceMap=1',
                    ].join('!')
            },
        ]
    }
}

postcss.config.js

const argv = {
    verbose:    _.includes(process.argv, '-v') || _.includes(process.argv, '--verbose'),
    json:       _.includes(process.argv, '--json'),
    production: _.includes(process.argv, '--production'),
};
module.exports = {
    plugins: [
        require('autoprefixer')({
            browsers: [
                "> 5%",            // https://www.netmarketshare.com/browser-market-share.aspx?qprid=2&qpcustomd=0
                "last 2 versions", // http://caniuse.com/
            ]
        }),
        require('postcss-url-mapper')(function(url) {
            return argv.production ? url : url.replace(new RegExp('^/'), 'http://localhost:3000/');
        })
    ]
};