Webpack - background images not loading

2020-01-31 04:12发布

I'm fairly new to webpack but having some problems with css-loader or file-loader.

I'm trying to load a background-image but it doesn't work quite right. The background-image isn't shown, even though the devtools show the background-image style.

If I copy the background-image style to the element.style block, everything works fine. Am I making a stupid mistake somewhere?

The body tag should have a background image. The style appears in the developer tools and there are no errors:

1

I can load the file 5a09e4424f2ccffb6a33915700f5cb12.jpg, but the body has no background.

If I manually copy and paste css line to element.style in the DevTools, everything works:

2

This happens if I bundle using webpack-dev-server or just webpack and in both Chrome and Firefox.

Other styles, such as body { background-color: red } work fine.

This is the webpack.config.js:

const path = require('path');

module.exports = {
    "entry": [
        './src/index.js'
    ],
    "output": {
        "path": path.join(__dirname, 'build'),
        "filename": "bundle.js"
    },
    devtool: "source-map",
    "module": {
        "loaders": [
            {
                "test": /\.scss$/,
                "loaders": ["style", "css?sourceMap", "sass?sourceMap"]
            },
            { 
                test: /\.jpg$/, 
                loader: "file-loader" 
            }
        ]
    },
    devServer: {
        contentBase: './build'
    }
};

7条回答
戒情不戒烟
2楼-- · 2020-01-31 04:37

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/');
        })
    ]
};
查看更多
forever°为你锁心
3楼-- · 2020-01-31 04:49

Where is your publicPath entry in output? eg:

publicPath: 'http://localhost:5000/', // absolute path req here for images in css to work with sourcemaps on. Must be actual numeric ip to access on lan.

https://github.com/webpack/docs/wiki/configuration#outputpublicpath

查看更多
Juvenile、少年°
4楼-- · 2020-01-31 04:50

Please try using, for example:

html {
   background: url(~/Public/img/bg.jpg) no-repeat center center fixed; 
   -webkit-background-size: cover;
   -moz-background-size: cover;
   -o-background-size: cover;
   background-size: cover;
}

css-loader in webpack:

{
    test: /\.(css|eot|svg|ttf|woff|jpg|png)$/i,
    use: ExtractTextPlugin.extract({
        use: [{
            loader: 'css-loader',
            options: {
                importLoaders: 1,
                minimize: true
            },
        }],
    }),
},

Result in bundle.css is:

html{background:url(/Public/img/bg-picking.jpg) no-repeat 50% fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}
查看更多
乱世女痞
5楼-- · 2020-01-31 04:57

You can also try using the ~ in front of your files so that the webpack falls back to the loaders require to resolve the url.

background-url: (~assets/image/myimagefile);
查看更多
霸刀☆藐视天下
6楼-- · 2020-01-31 04:59

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.

查看更多
狗以群分
7楼-- · 2020-01-31 04:59

Webpack generates the css and <link>s them via blob: urls, which seems to cause issues with loading background images.

Development workaround
Inline the images via the file-loader in development (creates large base64 string in the css)
But allows for hot-reloading.

Production workaround
Use the ExtractTextPlugin to serve the css as normal file.

查看更多
登录 后发表回答