create-react-app中Source maps显示异常如何正确映射源码

问题场景
调试create-react-app项目时,Chrome开发者工具控制台的调用栈前两行均指向instrument.js,第三行可正常映射到源文件Toolbar.tsx,项目Source maps由webpack生成,需要调整配置实现全链路源码位置正确映射。
根因说明
instrument.js不属于业务代码文件,一般来自三类场景:React开发环境注入的运行时代码、webpack HMR/React Refresh热更新注入的脚本、React DevTools浏览器扩展注入的调试代码。映射失败要么是source map生成规则没有覆盖这部分注入代码,要么是浏览器缓存了旧的映射文件,少部分情况是devtool配置选型不对导致映射丢失。
可落地解决方法
按优先级从高到低排查:
- 先排除缓存问题
打开DevTools设置面板,在网络分类下勾选「DevTools打开时停用缓存」,随后按Ctrl+Shift+R(Windows)/Cmd+Shift+R(Mac)硬刷新页面,大部分偶发的映射异常都是旧source map缓存导致的。 - 排查浏览器扩展影响
打开Chrome扩展管理页,暂时禁用React DevTools后刷新页面,如果此时调用栈里的instrument.js条目消失,说明是扩展注入的代码导致的,把React DevTools更新到最新版本即可,不需要修改项目配置。如果instrument.js的路径是chrome-extension://开头,可直接判定是扩展问题,和项目配置无关。 - 调整webpack devtool配置
如果是未eject的CRA项目,用craco/react-app-rewired覆盖webpack配置,开发环境将devtool设置为eval-source-map,替换CRA默认的eval-cheap-module-source-map——cheap模式会省略列映射、跳过loader层的源码映射,很容易丢失注入脚本的映射关系。配置参考:
如果是已经eject的项目,直接修改// craco.config.js module.exports = { webpack: { configure: (config) => { if (config.mode === 'development') { config.devtool = 'eval-source-map' } return config } } }webpack.config.js里的devtool字段即可,同时检查source-map-loader的规则,不要排除react-dev-utils、react-refresh这类开发依赖的目录,保证这部分注入代码的source map能被正常加载。 - 生产环境映射异常处理
生产构建时把devtool设置为source-map,不要用hidden-source-map、nosources-source-map这类不携带原始源码信息的配置,如果不想把source map部署到公网,可以通过Chrome DevTools的Workspace功能本地关联源码实现映射。
内容的提问来源于stack exchange,提问作者Devisfun
相关产品推荐
相关产品推荐

