1

I have been been struggling with an issue with Webpack. I have tried searching everywhere online for a solution but did not manage to solve my problem.

I am building a React application with the following project structure:

package.json
webpack.config.js
src
- images
- components
-- Display
--- Display.js
--- config.js
- Frame
-- Frame.js
index.js
index.html

Here is webpack.config.js:

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

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
    publicPath: "/"
  },
  module: {
    rules: [
      { test: /\.(js)$/, use: "babel-loader" },
      {
        test: /\.(jpg|png|gif)$/,
        use: {
          loader: "url-loader",
          options: {
            name: "[name].[ext]"
          }
        }
      },
      { test: /\.css$/, use: ["style-loader", "css-loader"] },
      { test: /\.json$/, loader: "json-loader" }
    ]
  },
  mode: "development",
  plugins: [
    new HtmlWebpackPlugin({
      template: "src/index.html"
    })
  ]
};

config.js provides a variable with the image path to Display.js, which then passes it to Frame.js as a prop. Frame.js renders the image with the provided path.

//config.js
export const imgPath = "/src/images/icon.gif";

//Display.js
import {imgPath} from "./config.js";
<Frame imgSrc={imgPath} />

//Frame.js
<img src={this.props.imgSrc} />

The problem I am facing is that the image icon.gif is not put in-line in the javascript bundle but instead the browser makes a request to fetch the file, which is not the expected behaviour. When I build the application in production mode, the image is not displayed at all.

Could someone please help me get this right? Basically, there are two problems I am facing:

  1. The images are not made inline by the url-loader
  2. The images are not displayed at all in production build.

Thank you!

craig-nerd
  • 718
  • 1
  • 12
  • 32

1 Answers1

0

You have to import the file first. But since your publicPath is set to '/', and your images are emitted into dist, the actual path to the image you need to use is /icon.gif.

1) Import all the possible files (Be sure to use the correct path here)

// includes.js

import './src/images/icon1.gif';
import './src/images/icon2.gif';
import './src/images/icon3.gif';

2) Export the production file path function

//config.js

import './includes.js';

export const imgPathFunc = num => `/icon${num}.gif`;

3) Import it in Display.js

//Display.js

import { imgPath } from "./config.js";

{serverResponse && <Frame imgSrc={imgPath(serverResponse)} />}
Siri
  • 1,117
  • 6
  • 13
  • Thank you for your answer! For part (1) do I need to import that in `config.js`? Also, I did try using the approach of importing images. However, this isn't a neat solution for my case because I am generating the path dynamically in `config.js`. Something like, `export const imgPath="/icon"+{some variable}+".gif"`, and there are many many images like these. Sorry, I should've stated that in my question. Is there any other way to solve this problem? – craig-nerd Jul 04 '19 at 05:59
  • @Jspake Yes you will need to import them first. Do you know the names and paths of all the images you want to import? – Siri Jul 04 '19 at 06:04
  • Yes, I do know the path names. But the images to be rendered keep changing depending on the data that I receive from the server. This is the problem. – craig-nerd Jul 04 '19 at 07:03
  • @Jspake Well, in that case, you have to make sure any image path you get from the server is already included as part of the build. – Siri Jul 04 '19 at 07:05
  • I mean, the server only gives me a variable needed to form the image path. I do not actually get the entire path from the server – craig-nerd Jul 04 '19 at 07:08
  • @Jspake Can you give an example of a network response, and an image path please? – Siri Jul 04 '19 at 12:13
  • So from the network response, I get a number between 1 and 9 in a variable, let's call this `serverResponse`. Then in config.js, I export the path as, `export const imgPath = "/src/images/icon"+serverResponse+".gif"`; – craig-nerd Jul 04 '19 at 18:21
  • @Jspake Updated answer. – Siri Jul 04 '19 at 18:30
  • Thank you, @Sreeram. Quick question: where exactly should I import all the possible files (from part 1)? – craig-nerd Jul 05 '19 at 06:12
  • @Jspake It will be good to import put it in a separate file and import this file into config.js. – Siri Jul 05 '19 at 07:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/196052/discussion-between-jspake-and-sreeram). – craig-nerd Jul 05 '19 at 14:59