jsstuball
jsstuball

Reputation: 4951

Webpack bundles PNG image but React won't display it

As the title says, webpack builds without complaint. And I can see the image file has been copied to the bundle output dist directory, so presumably the test part of the config is correct at least.

But the webpage can't locate it, it's just a broken image square. I must have read about 15 existing SO posts but here I am. I've tried both import version and require version:

import red_light from './red_light.png';

... or alternatively...

const red_light = require('./red_light.png');

with

<img src={red_light} />

Both fail to locate the image and load it onto the page.

Also tried directly requiring in the JSX:

<img src={require('./red_light.png')} />.

Fails too.

Webpack rules config:

...
rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {loader: "babel-loader"}
      },
      {
        test: /\.css$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              modules: false
            }
          }
        ]
      },
      {
        test: /\.(jpg|png|svg)$/,
        loader: 'file-loader',
        // options: {
        //   name: '[path][name].[ext]',
        // },
      },
    ]
...

I don't know what could be causing my setup not to work.

This seemed interesting to me: in browser when inspecting the emitted html, it just says src=[Object module] instead of any URL. Maybe this is normal. When I hover my mouse it just says 'Could not load the image'.

Edit: I've discovered it works in dev mode but not prod mode, i.e. when everything's in RAM it all works out, but if I do an npm run build it emits the image(s) to (a sub-directory of) the configured webpack output directory, but the relative imports don't appear to be working inside the target index.bundle.js. The prod html file can import the emitted js index file fine of course, since the page loads. I don't see why webpack doesn't have enough information to configure the correct relative import since i) it emitted the png file itself and ii) it can see the react source code and knows where every component is relative to the corresponding entry point. Basically to make it work it looks like in prod I would have to import the png file into the react file but for the src attribute inside the img tag, manually write in an relative path as an external file.

url-loader is working fine, however, as there's no vector for confusion with relative imports in target versus src.

Upvotes: 1

Views: 2212

Answers (1)

Tony
Tony

Reputation: 20162

It should be like this

{
  test: /\.(jpe?g|png|gif)$/i,
  loader: "file-loader"
},

You can view my full config here

Update: Normally webpack try to search the file that live within the output dir in your config like this

output: {
    path: path.resolve(__dirname, "wwwroot/dist"),
    filename: "[name].js",
    publicPath: "/dist/"
},

So it will look for the file inside the wwwroot folder

Upvotes: 1

Related Questions