Search code examples
reactjswebpackwebpack-2

Webpack & React. Loaded image can't resolve path 404


At this case I am trying to set up sort of high-order component and further implement 'dynamic' image loads for it. Can you please explain what has been done wrong in order to reference to the inside the component.

React Component

class Slide extends Component {
  constructor(props) {
    super(props)
  }

  render () {

    let imageLeft = {
     backgroundImage: 'url(./assets/introleft.png)'
    }

    return (
      <div className={styles.someStyles}>
        <div className={styles.someStyles} style={imageLeft} >&nbsp;</div>
      </div>
    )
  }

}

... state

export default connect(mapStateToProps)(Slide);

Project structure

enter image description here

Webpack config

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

module.exports = {
  entry: [
    'react-hot-loader/patch', 
    'webpack-dev-server/client?http://localhost:8080', 
    'webpack/hot/only-dev-server',  
    './index.js'
  ],
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'build'), 
    publicPath: '/'
  },  
  context: path.resolve(__dirname, 'logic'), 
  devtool: 'inline-source-map',    
  devServer: {
    hot: true, 
    contentBase: path.resolve(__dirname, 'build'),
    publicPath: '/'
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          'babel-loader',
        ],
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader?modules',
          'postcss-loader',
        ],
      },{
        test: /\.png$/,
        use: { loader: 'url-loader', options: { limit: 15000 } },
      },
      {
        test: /\.svg$/,
        use: {
          loader: 'svg-url-loader',
          options: {}
      }
    ],
  },

  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new HtmlWebpackPlugin({
      template: './index.template.html'
    })<script> tag
  ],
};

P.S: Project has no node.js server, just wepback-dev. So react-router uses hash history /#, wounder if it somehow affects the webpack publicPath property.


Solution

  • When you're using backgroundImage: 'url(./assets/introleft.png)', this will be inserted as is (it's just a string), so your url-loader won't be applied to it. Instead you should import the image:

    import introleft from './assets/introleft.png';
    

    Webpack will have applied the url-loader and you get back either the data URL or the URL to the extracted image, if the size was too big. All you need to do now is put that URL into your backgroundImage:

    backgroundImage: `url(${introleft})`