57

I am making a React w/ Webpack setup and am struggling to do what seems like should be a simple task. I want webpack to include images, and minimize them like I with gulp but I can't figure it out. I just want to be able to link an image in my css like so:

/* ./src/img/background.jpg */

body { background: url('./img/background.jpg'); }

I have all of my css/js/img folders inside a src folder. Webpack outputs to a dist folder, but I can't figure out how to get images there.

Here is my webpack setup:

 var path = require('path');
 var webpack = require('webpack');
 var HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
  devtool: 'cheap-eval-source-map',
  entry: [
   'webpack-dev-server/client?http://localhost:8080',
   'webpack/hot/dev-server',
   './src/index.js'
  ],
  output: {
  path: path.join(__dirname, 'dist'),
  //  publicPath: './dist',
  filename: 'bundle.js'
  },
  plugins: [
  new webpack.HotModuleReplacementPlugin(),
  new HtmlWebpackPlugin({
  template: './src/index.html'
   })
  ],
  module: {
  loaders: [{
   exclude: /node_modules/,
   test: /\.js?$/,
   loader: 'babel'
   }, {
  test: /\.scss$/,
  loader: 'style!css!sass'
    }, {
  test: /\.(png|jpg)$/,
  loader: 'file-loader'
  }]
 },

 devServer: {
  historyApiFallback: true,
  contentBase: './dist',
  hot: true
  }
};
user3737841
  • 655
  • 1
  • 8
  • 10

2 Answers2

88

I was stuck with similar issue and found that you can use url-loader to resolve "url()" statements in your CSS as any other require or import statements.

To install it:

npm install url-loader --save-dev

It will install the loader that can convert resolved paths as BASE64 strings.

In your webpack config file use url-loader in loaders

{
  test: /\.(png|jpg)$/,
  loader: 'url-loader'
}

Also make sure that you are specifying your public path correctly and path of images you are trying to load.

Sumner Evans
  • 8,951
  • 5
  • 30
  • 47
WitVault
  • 23,445
  • 19
  • 103
  • 133
  • 3
    Well my webpack-dev server serves from /dist and my images are in /src so do you know how I would reference the images in my .css file? Are the images supposed to be rolled up with my bundle.js? I'm just not sure how to get them to /dist since the /dist folder is just a virtual one served from webpack-dev-server – user3737841 Feb 12 '16 at 20:06
  • 4
    @user3737841 You should be able to `require` the images in your stylesheets. For example, `background-image: url('../assets/img/logo-dark.png')`. You will just have to try/adjust to get the path correct. – Alex Klibisz Feb 13 '16 at 07:45
  • 1
    Is it possible to achieve the same end result without inlining images? Ideally, images should just be copied to the dist folder preserving the same relative path. Is this possible? – VariableContent Apr 26 '16 at 02:34
  • 1
    @VariableContent yes, just use file-loader. Images will be copied into output folder. – Skay Aug 18 '16 at 18:29
  • 4
    @VariableContent btw url-loader has an option `limit` and if the image is larger than limit it will resolve it to url rather than base64 string – SMSk Apr 17 '17 at 14:20
  • You can use file-loader `{test: /\.(png|jpg)$/, loader: 'file-loader', }` – Abhishek Aug 13 '17 at 19:29
  • @WitVault, `file-loader` vs `url-loader`? Which one should followed by other in webpack.config? – Green Mar 14 '18 at 09:34
  • @Green first use url-loader then file-loader should be used as fallback – WitVault Mar 14 '18 at 11:53
  • what should i put in the url, a relative address or complete one? – Shubham Bhewanewala Jul 13 '18 at 08:34
  • what should be the location of image in project directory? – Shubham Bhewanewala Jul 13 '18 at 08:59
  • Thank you for this! Helped me out massively! – steffcarrington Sep 19 '18 at 16:25
  • There aren't any examples of how to import this into css. I need to use require? In CSS? How does that look, and what is the path relative to? – BBaysinger Nov 12 '19 at 07:35
  • Isn't it possible to replace file-loader with asset modules in webpack5 ? I tried as it is being said in docs , but couldn't succeed . – Anoop D Nov 23 '20 at 05:47
0

using background-image: url('./img/background.jpg') in the scss file worked for me, without url-loader. Only had file-loader for .png|.jpg|... etc.