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

Webpack 4动态导入JSON模块找不到问题求助

解决Webpack 4动态加载JSON文件找不到模块的问题

问题本质

你遇到的核心问题是Webpack 4对动态require的静态分析限制。当你用require(@res/level/${this.level}.json)这种写法时,Webpack在静态构建阶段没法把别名@res和动态变量this.level结合起来,正确识别到src/res/level目录下的JSON文件范围。而watch模式下修改代码会触发增量构建,Webpack会重新扫描目录,意外补上了静态分析阶段漏掉的文件,所以临时能正常加载。

具体解决方案

1. 用require.context预加载目标目录(最推荐)

这是Webpack官方推荐的批量处理动态模块的方案,提前告诉Webpack要扫描的目录和文件规则,构建时会把所有匹配的文件打包进去,运行时就能动态获取:

// 在需要加载JSON的文件顶部,创建一个上下文
const levelFiles = require.context('@res/level', false, /\.json$/);

// 之后动态获取对应文件
const currentLevelData = levelFiles(`./${this.level}.json`);

参数说明:

  • 第一个参数:要扫描的目录(这里用别名@res/level没问题,Webpack能正确解析)
  • 第二个参数:是否递归扫描子目录(你的文件都在level根目录,设为false即可)
  • 第三个参数:匹配文件的正则表达式(这里匹配所有.json文件)

这种方式能彻底解决静态分析的问题,不管是正常构建还是watch模式都能稳定运行。

2. 静态指定目录范围,只动态替换文件名

如果你不想用require.context,可以把目录部分静态写死,只让变量替换文件名,让Webpack能静态识别到要扫描的目录:

// 确保目录部分是静态的,只动态替换文件名
require(`@res/level/${this.level}.json`);

不过这种写法依赖Webpack对别名的静态解析,有时候可能还是会出问题,不如require.context可靠。如果还是不行,可以换成相对路径:

// 用相对路径代替别名,让Webpack直接识别到目录
require(`../res/level/${this.level}.json`);

3. 优化Webpack别名与模块搜索配置

虽然你已经配置了别名,但可以补充modules配置,让Webpack优先搜索src目录,辅助静态分析:

resolve: {
  extensions: [".ts", ".js", ".glsl", ".json"],
  modules: [path.join(__dirname, 'src'), 'node_modules'], // 添加src到模块搜索路径
  alias: {
    "@res": path.join(__dirname, "src/res"),
    "@lib": path.join(__dirname, "src/lib"),
    "@shader": path.join(__dirname, "src/shader"),
    "@control": path.join(__dirname, "src/control"),
    "@scene": path.join(__dirname, "src/scene"),
    "@util": path.join(__dirname, "src/util"),
  }
}

为什么watch模式下能正常加载?

watch模式下,当你修改代码触发增量构建时,Webpack会重新扫描相关目录的文件变化,这时候它会把之前静态分析阶段没识别到的JSON文件加入到模块集合中,所以临时能加载成功,但这只是增量构建的“副作用”,正常构建时静态分析阶段没包含这些文件,就会抛出找不到模块的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:06