You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack 5无法从JSON文件加载图片的问题求助

问题:Webpack未处理JSON中引用的图片资源

在HTML中直接使用<img>标签时,Webpack可正常处理图片资源——自动添加哈希值并输出到images文件夹;但通过JavaScript读取JSON文件中的图片URL,动态生成<img>标签插入页面时,图片路径未带上哈希值,且目标图片未被打包到images文件夹,Webpack完全跳过了这类图片的处理。

JSON数据

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

Webpack配置

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(),
  ],
};

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();

项目结构

项目文件结构如下:

  • 项目根目录
    • src/
      • js/
        • index.js
      • json/
        • data.json
      • images/
        • avatars/
          • image-alex.png
          • image-tom.png
      • index.html
    • webpack.config.js

解决方案

问题根源

当前配置中,JSON文件被当作asset/resource处理,仅被复制到dist/data目录,Webpack不会解析JSON内部的图片路径,因此这些图片URL无法被识别处理,自然不会被打包和添加哈希值。

解决步骤

  1. 调整JSON文件的Webpack规则
    将JSON的处理从asset/resource改为让Webpack解析其内部内容的配置,修改Webpack配置中的JSON规则:

    {
      test: /\.json$/i,
      type: 'javascript/auto', // 禁用asset模式,让Webpack解析JSON内容
      loader: 'json-loader' // 若未安装需先执行:npm install json-loader --save-dev
    }
    
  2. 修改JavaScript代码,动态导入图片
    直接从JSON读取的路径无法被Webpack识别,需通过动态导入让Webpack处理图片资源,替换原JavaScript代码为:

    import data from "../json/data.json";
    const containerEl = document.querySelector(".all-persons-container");
    
    // 批量加载并处理图片资源
    const loadImages = async (persons) => {
      return Promise.all(persons.map(async (person) => {
        // 动态导入图片,让Webpack识别并处理
        const imgAsset = await import(`../${person.image}`);
        return { ...person, image: imgAsset.default };
      }));
    };
    
    const insert = async () => {
      const processedPersons = await loadImages(data.persons);
      // 生成带处理后图片路径的HTML
      const markup = processedPersons.map(person => `
        <img src="${person.image}" alt="avatar" />
      `).join('');
      containerEl.insertAdjacentHTML("afterbegin", markup);
    };
    
    insert();
    
  3. 验证效果
    重新执行Webpack打包,此时JSON中的图片会被Webpack处理,添加哈希值并输出到dist/images目录,动态生成的<img>标签会使用正确的打包后路径。

补充说明

  • Webpack 5内置了json-loader,但需设置type: 'javascript/auto'才能避免将JSON当作静态资源处理。
  • 动态导入时,图片路径需是Webpack可静态分析的格式,这里../${person.image}符合要求,因为JSON中的路径是固定相对路径。

内容的提问来源于stack exchange,提问作者Alamin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 02:34:54