Search code examples
cssimagewebpackurlloaderwebpack-file-loader

Webpack file-loader and images in CSS


I'm using images in my stylesheet (less) fine by doing:

.foo { background: url('../images/foo.png') }

When using HMR they're base64 encoded into the stylesheet which I'm fine about. However when compiling for production I want the images not to be embedded in the stylesheet. I've tried both url-loader and file-loader.

With url-loader I couldn't get it to emit the images properly. If I set no limit then the files were emitted to output/images/ and had the right size but weren't valid images. If I set the limit to something smaller than 8k the images were emitted to output and correct.

In either case the emitted images appeared in the CSS like so (example when using url-loader with limit=1):

url(data:image/png;base64,bW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcHVibGljX3BhdGhfXyArICJhMDdjZWVkMGRiZTNlMjk5ODY5NWQ3ZjM4MzYxZDY1Zi5wbmciOw==);

Which when you decode it is:

module.exports = __webpack_public_path__ + "a07ceed0dbe3e2998695d7f38361d65f.png";

How do I get the css to use the URL rather than trying to base64 encode the value?

This is my webpack (still on webpack 1) loaders config:

{
    test: /\.jsx?$/,
    loader: 'babel-loader',
    exclude: /node_modules/,
},
{
    test: /\.css$/,
    loader: ExtractTextPlugin.extract('style-loader', 'css!postcss'),
},
{
    test: /\.less$/,
    loader: ExtractTextPlugin.extract('style-loader', 'css!less!postcss'),
},
{
    test: /\.(png|jpg|gif)$/,
    loader: 'file-loader?name=/images/[name].[ext]'
}

Update: Turns out disabling the less-loader stops the URLs from being encoded when using the url-loader (but the images are still not valid) but not when using the file-loader.

Update 2: Added a custom loader at the end of the css!less!postcss loaders and the source still has the image URL of ../images/foo.png so it appears the issue is further down the line. Also tried removing the ExtractTextPlugin but the compiled JS for the image then has the Base64 encoded value for the export like the CSS does.


Solution

  • It seems that having the 2 ExtractTextPlugins (for the css & less tests were causing the problems) as I don't have any css files I removed the first and it's now working as expected.