1

I am developing a SpringBoot/React project that also uses webpack. I am simply trying to render an image that is stored locally in the project. I have tried using npm's file-loader endlessly, but to no avail. Whenever I run the application, I get a 404 error with the image I am trying to load.

I have also tried using url-loader and image-webpack-loader but both also result in a 404 error.

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/main/js/index.js',
  devtool: 'sourcemaps',
  cache: true,
  debug: true,
  output: {
    path: __dirname,
    filename: './src/main/resources/static/built/bundle.js',
  },
  module: {
    loaders: [
      {
        test: path.join(__dirname, '.'),
        exclude: /(node_modules)/,
        loader: 'babel',
        query: {
          cacheDirectory: true,
          presets: ['es2015', 'react'],
        },
      },
      {
        test: /\.css$/,
        loaders: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader: 'file-loader',
      },
    ],
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: ['babel-loader', 'eslint-loader'],
      },
      {
        test: /\.(png|jpe?g|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'img/[hash]-[name].[ext]',
            },
          },
        ],
      },
    ],
  },
};

header.js

import './css/header-style.css';
import React from 'react';
import Logout from './Logout';
import { Link } from 'react-router-dom';

import logo from './img/Logo.png'; // The image I'm trying to load.

/**
 * Renders Logo, header navigation links to other pages, and the logout component.
 */
function Header() {
  return (
    <div className="row wrapper-header">
      <nav className="navbar navbar-expand-lg">
        <a className="navbar-brand" href="#">
          <img className="logo-width" alt="Logo" src={logo} />
        ...

Project Structure

+-- ProjectFolder
|   +-- src
|      +-- main
|          +-- js
|              +-- img
|                  +-- Logo.png
|              +-- header.js
|
|   +-- f5c281d45d55b24ed52c9fee3077f36e.png

When I run webpack as well, I can see that it emits the png with the hash it gives it, as such: in the root ProjectFolder directory f5c281d45d55b24ed52c9fee3077f36e.png

FortunateSonn
  • 11
  • 1
  • 2

1 Answers1

1

My guess is that your HTML page is referring to ./built/bundle.js, the path to the React App relative to the Spring static resource directory. Webpack will have output the image file into the same location (...../static/built/imagehash.png) as the bundle.js with a hash like you say. When the React App refers to the image, it will use a relative path, like imagehash.png, assuming it's in the same directory. But when Spring sees that path, it will look for static/imagehash.png (and other static resource locations). Ie. It doesn't know to look in the static/built/ directory.

You can use the publicPath option to tell the file-loader where to reference the image from on the web server. Like this:

        {
            test: /\.(png|svg|jpg|gif)$/,
            loader: 'file-loader',
            options: {
                publicPath: 'built'
            }
        }
rewolf
  • 5,561
  • 4
  • 40
  • 51