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
- avatars/
- index.html
- js/
- webpack.config.js
- src/
解决方案
问题根源
当前配置中,JSON文件被当作asset/resource处理,仅被复制到dist/data目录,Webpack不会解析JSON内部的图片路径,因此这些图片URL无法被识别处理,自然不会被打包和添加哈希值。
解决步骤
调整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 }修改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();验证效果
重新执行Webpack打包,此时JSON中的图片会被Webpack处理,添加哈希值并输出到dist/images目录,动态生成的<img>标签会使用正确的打包后路径。
补充说明
- Webpack 5内置了
json-loader,但需设置type: 'javascript/auto'才能避免将JSON当作静态资源处理。 - 动态导入时,图片路径需是Webpack可静态分析的格式,这里
../${person.image}符合要求,因为JSON中的路径是固定相对路径。
内容的提问来源于stack exchange,提问作者Alamin
相关产品推荐
相关产品推荐

