Alessander França Alessander França - 3 months ago 167
Sass (Sass) Question

Webpack not loading background image

I am trying to load a image:

background: transparent url("../img/select-icon.png") no-repeat center right 8px;


At my style.scss and it is not working

Here is my webpack.config:

function _path(p) {
return path.join(__dirname, p);
}

module.exports = {

context: __dirname,
entry: [
'./assets/js/index'
],

output: {
path: path.resolve('./assets/bundles/'),
filename: '[name].js'
},

devtool: 'inline-eval-cheap-source-map',

plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
new HappyPack({
id: 'jsx',
threads: 4,
loaders: ["babel-loader"]
})

],

module: {
loaders: [
{
test: /\.css$/,
include: path.resolve(__dirname, './assets/css/'),
loader: "style-loader!css-loader"
},

{
test: /\.scss$/,
include: path.resolve(__dirname, './assets/css/'),
loader: "style-loader!css-loader!sass-loader"
},

{
test: /\.jsx?$/,
include: path.resolve(__dirname, './assets/js/'),
exclude: /node_modules/,
loaders: ["happypack/loader?id=jsx"]
},
{
test: /\.png$/,
loader: 'file-loader'
}
]
},

resolve: {
modulesDirectories: ['node_modules'],
extensions: ['', '.js', '.jsx'],
alias: {
'inputmask' : _path('node_modules/jquery-mask-plugin/dist/jquery.mask'),
},
}
}


I am using file-loader but the url rendered at browser does not match with the url of the image.

I think that I not using source map: https://github.com/webpack/style-loader/issues/55

Can anyone help?

Answer

To resolve the url('...') to the file output path you need to use resolve-url-loader before the css-loader.

In your webpack.config.js you need to make the following changes:

//...
module: {
    loaders: [
        {
            test: /\.css$/,
            include: path.resolve(__dirname, './assets/css/'),
            loader: "style-loader!css-loader!resolve-url-loader"
        },

        {
            test: /\.scss$/,
            include: path.resolve(__dirname, './assets/css/'),
            loader: "style-loader!css-loader!resolve-url-loader!sass-loader"
        },
        //...
    ]
}
//...

As an optional configuration, you can specify the filename template that the file-loader uses. So instead of having 96ab4c4434475d0dā€Œā€‹23b82bcfc87be595.png for instance, you can have /img/select-icon.png.

In your webpack.config.js the default options of the file-loader are being used. This means that the output filename is using the template [id].[ext]. Being [id] the chunk id and [ext] the extension of the file.

To specify the output filename template you need to pass the name parameter to the query of the loader.

Up to this point, require('../img/select-icon.png') should return '/img/select-icon.png'. The resolve-url-loader will use this value.

//...
module: {
    loaders: [
        //...
        {
            test: /\.png$/,
            loader: 'file-loader',
            query: {
                name: 'img/[name].[ext]'
            }
        },
        //...
    ]
}
//...
Comments