必须将webpack运行在可调试的node.js进程里:修改package.json的build脚本为"node --inspect-brk=5858 ./node_modules/webpack/bin/webpack.js --config webpack.config.js",launch.json中runtimeexecutable设为node、runtimeargs传对应参数,并在webpack.config.js顶层或plugin的apply方法打断点。

Webpack 构建出错时,直接看终端报错往往找不到根因;必须进 VSCode 调试器里单步执行,才能看清 loader/plugin 是在哪一步被调用、参数怎么传、返回值是否符合预期。
怎么让 VSCode 进入 Webpack 本身(不是业务代码)的调试流程
关键不是配 devtool,而是让 Webpack 运行在可调试的 Node.js 进程里。默认 npm run build 是黑盒执行,VSCode 没法介入。
- 把 package.json 的构建脚本改成:
"build": "node --inspect-brk=5858 ./node_modules/webpack/bin/webpack.js --config webpack.config.js" - launch.json 配置中
runtimeExecutable设为node,不是npm;runtimeArgs直接传上面那条命令拆解后的参数(避免多一层 shell 封装导致调试端口失效) - 断点打在
webpack.config.js顶层或 plugin 的apply方法里——Webpack 启动后第一件事就是加载并执行 config,这里卡住就能确认是否读到配置 - 如果用的是
vue-cli-service或react-scripts,得换成它们内部调用的 Webpack 入口路径,比如./node_modules/@vue/cli-service/node_modules/webpack/bin/webpack.js,否则断点不命中
为什么断点打在 loader 或 plugin 里没反应
loader 和 plugin 的执行时机不同:loader 在模块解析阶段运行,plugin 在 compiler 生命周期钩子上触发。断点位置不对,就等于没打。
- loader 断点要打在函数体内部,且确保该 loader 确实被命中(检查
module.rules的test正则是否匹配文件路径,注意 Windows 下路径分隔符是\,但 Webpack 内部统一转成/) - plugin 断点优先打在
apply(compiler)函数开头,再根据需要加在compiler.hooks.emit.tap这类具体钩子回调里 - 某些 loader(如
babel-loader)内部用了fork子进程,VSCode 默认不跟进子进程调试;此时需改用cache: false+sourceMap: true强制走主进程,或换用ts-loader这类同步 loader 方便调试 - 不要在
require('xxx-loader')这行打断点——那是引入时刻,不是执行时刻
sourceMapPathOverrides 配错会导致断点“灰掉”,但错误不报
VSCode 不会提示映射失败,只会静默跳过。断点变空心圆,说明它根本没找到源文件对应关系。
- 先在 Chrome DevTools 的 Sources 面板里右键压缩 JS → “Reveal in sidebar”,看左侧显示的原始路径,例如
webpack:///./src/utils/request.ts - 对比你本地文件真实路径,比如
/Users/me/project/src/utils/request.ts,那么映射就得写成:"webpack:///./src/*": "${webRoot}/src/*" - 注意
${webRoot}是 launch.json 里配置的路径,不是process.cwd();如果项目在 monorepo 子包里,${webRoot}必须设为该子包根目录,不能设整个 workspace 根 - 多个规则有顺序,靠前的先匹配;若同时存在
"webpack:///src/*"和"webpack:///./src/*",后者更精确,应放前面
调试时修改了 webpack.config.js 却没生效
因为 Webpack CLI 会缓存 config 文件内容,尤其在 watch 模式下。改了配置不重启,调试器看到的还是旧对象。
- 每次改完
webpack.config.js,必须完全退出当前调试会话(不是暂停),再重新按 F5 启动 - 不要依赖 HMR 或
--watch来热更新 config —— 它们只监听 entry 文件和 module,不监听 config 本身 - 可以在 config 顶部加
console.log('config loaded at', Date.now()),配合终端输出确认是否真被重载 - 某些封装工具(如 vue-cli-service)会把 config 包一层 wrapper,实际执行的是生成的临时 config 文件,这时得去
node_modules里找真正被 require 的路径
真正卡住的地方,往往不是哪行代码写错了,而是调试会话没连上真实的 Webpack 执行上下文,或者路径映射差了一个点、一个斜杠、一个层级。











