VSCode调试React应用的核心前提是开发服务器已运行且输出source map,以及launch.json中url和webRoot严格匹配实际路径;其余问题基本源于这两点未对齐。

VSCode 调试 React 应用不是“点一下就灵”,核心前提只有两个:开发服务器必须已运行且输出 source map,launch.json 中的 url 和 webRoot 必须严格匹配实际路径。其余所有问题——断点不红、跳转到 bundle.js、变量显示 undefined——基本都源于这两点没对齐。
断点不生效?先查浏览器 Sources 里有没有 webpack://
这是最快速的诊断动作:打开 Chrome 开发者工具 → Sources 标签页 → 展开左侧 localhost → 看是否有 webpack:// 或 app:// 前缀的源码树。没有,说明 source map 根本没生成或没被加载。
- CRA 项目:确认是
npm start(非npm run build),它默认开启devtool: 'source-map' - Vite 项目:检查
vite.config.ts是否含build: { sourcemap: true };开发时必须用vite命令启动,不能用vite build - Next.js:仅
next dev模式支持调试;若配置了output: 'export',客户端代码无法调试 - 自定义 Webpack:
devtool不能是'eval'或false,推荐'cheap-module-source-map',且mode必须为'development'
launch.json 配置错在哪?重点关注 url、webRoot、sourceMapPathOverrides
launch.json 不是复制粘贴就能用的模板,三项参数必须按项目结构校准:
-
url:必须与你手动启动的服务地址完全一致,比如 CRA 是"http://localhost:3000",Vite 默认是"http://localhost:5173",写错端口或协议(httpsvshttp)直接导致连接失败 -
webRoot:指向源码根目录,通常是"${workspaceFolder}";但若入口 HTML 在public/index.html,而构建产物输出到dist/,则需设为"${workspaceFolder}/public"或"${workspaceFolder}/dist",否则断点映射失败 -
sourceMapPathOverrides:解决路径别名或构建路径偏移,CRA 常见配置为{"webpack:///src/*": "${webRoot}/../src/*"};Vite 项目若用@/别名,可能需要加{"@/*": "${webRoot}/src/*"}
为什么断点是空心红点,或者停在 bundle.js 里?
空心红点 = VSCode 认为该位置无法命中;停在 bundle.js = source map 映射失败,调试器退回到了编译后代码。
- 确保浏览器是新弹出的窗口,而不是复用已有标签页——复用页不会加载 sourcemap
- 检查 Chrome 是否启用了 “Disable cache (while DevTools is open)”;缓存旧的 sourcemap 会导致映射错乱
- 在
useEffect(() => { }, [])第一行设断点,如果停在React.createElement调用栈里,说明sourceMapPathOverrides没生效,或webRoot指向错误目录 - 类组件中
componentDidMount断点有效,但函数组件中useState初始化值读取不到最新状态?这不是调试器问题,是 React 执行时机本身如此——断点只能捕获执行快照,不能改变异步更新逻辑
Expo / React Native 调试和 Web 完全不是一回事
Expo 项目不能套用 Web 的 pwa-chrome 配置,真机调试必须走 Expo Go App + WebSocket 连接,不是浏览器。
- 启动命令必须是
npx expo start,等控制台明确输出Metro waiting on http://localhost:19002后再启动调试 -
launch.json中url应为"http://localhost:19002",类型选"pwa-node"或 Expo 官方推荐的"expo"配置 - 断点只在 JS 文件内有效,不能打在 JSX 根节点或 hook 调用链过深的位置(V8 引擎限制)
- 代码保存后热更新,但断点状态不会自动恢复;需摇动设备 → “Reload” 才能重新注入调试器
真正卡住人的从来不是配置项数量,而是 url 和 webRoot 这两个字符串是否与当前运行态严丝合缝。多一次手动核对,比反复重装插件省两个小时。











