javascriptjsondebuggingwebpackwebpack-5

Why I can't load images from json file with webpack-5?


When I use the IMG tag in the html, it works just fine. But, when I'm trying to generate some HTML with an image URL (which is from the JSON file) in the Javascript and insert it, the images are being inserted, but not with the hash, and also the desired image is not being generated in the image folder. Webpack is just skipping it. I tried hard, but couldn't find a way. Please help me! I'm frustrated.

Here is my json data:

{
  "persons": [
    {
      "id": 1,
      "image": "./images/avatars/image-alex.png"
    },
    {
      "id": 1,
      "image": "./images/avatars/image-tom.png"
    }
  ]
}

Here is my Webpack config:

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  entry: "./src/js/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  mode: "development",
  devServer: {
    port: 2222,
    hot: false,
    open: true,
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
      {
        test: /\.html$/,
        loader: "html-loader",
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        type: "asset/resource",
        generator: {
          filename: "images/[name].[hash].[ext]",
        },
      },
      {
        test: /\.json$/i,
        type: "asset/resource",
        generator: {
          filename: "data/[name].[hash].[ext]",
        },
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css",
    }),

    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    new CleanWebpackPlugin(),
  ],
};

Here is my javascript:

import rawJson from "../json/data.json";
const containerEl = document.querySelector(".all-persons-container");

const dataJson = async () => {
  const response = await fetch(rawJson);
  const data = await response.json();
  return data;
};

let allPersons = await dataJson().then((data) => {
  return data.persons;
});

const img = allPersons[0].image;
console.log(img);

const insert = async () => {
  const markup = `
      <img
        src="${img}"
      />
    `;

  containerEl.insertAdjacentHTML("afterbegin", markup);
};

insert();

I also attached my project tree:Preject tree


Solution

  • The source image file must be imported or required in JavaScript:

    import img from "./images/avatars/image-alex.png";
    // OR
    const img = require("./images/avatars/image-alex.png");
    
    console.log(img); // => output image file
    

    The Webpack parses JS code and extracts required images at "server side" and the variable img will contains already processed output filename of image.

    But in runtime it is impossible, the Browser don't know where is your source image.