线上调试代码,试试SourceMap?

0 阅读3分钟

线上调试代码,试试 SourceMap?

背景

大家有没有过在开发环境代理调试的时候,只能调试打包之后的代码,而不是调试源码?

那是因为没正确使用 sourceMap


SourceMap

sourceMap 有什么作用?🤔

sourceMap 用于映射编译后的代码与源码,这样如果编译后的代码出错了,可以很快速的定位到源文件的位置。

举个栗子 🌰

image.png

umi 的项目在开发环境默认的 sourceMapcheap-module-source-map

我们把它关了,看看编译的资源有什么不一样的:

image.png

// config.ts
devtool: false,

既然 sourceMap 可以快速定位到源码的位置,为了方便,我们在页面上执行个 console.log,看看 log 位置的源代码:

image.png

console.log('测试 SourceMap')

image.png 打印出来发现我们 log 处的源码是编译之后的

目前不加 SourceMap 的结论 😳

不加 sourceMap,页面上的 log 信息是无法精准定位到源码的位置的。


那我们加了呢?

先试试 bigfish 默认的,我们把 config 里的 devtool 删掉。

image.png

结果发现还是定位不到源码位置,控制台提示:source map failed to load

而且文件最后一行已经显示了 sourceMappingURL 的指定文件。

那是为什么?map 文件加载失败了。

仔细看发现它请求的位置是线上环境的 map 文件,请求了 404。

而 umi 在生产环境不会打开 sourceMap(为了防止其他人可以随意在 source 上看到自己的源码)。

image.png

奇怪的是我们在 Network 里并没发现请求的 map 文件。

image.png

查阅资料发现:

SourceMap 的加载不能从 Network 中看到,而要从 Developer Resources 看到。

打开 Developer Resources:command + shift + p 搜索 Show Developer Resources

image.png

在 Developer Resources 中可以看到 map 文件请求失败:

ERROR LOADING URL http://xxx.alipay.net/static-assets/.../P_ALARMLABELMANAGEMENT_INDEX.ASYNC.JS.MAP:
HTTP ERROR: STATUS CODE 404, NET::ERR_HTTP_RESPONSE_CODE_FAILURE

image.png

用 XSwitch 转发 map 文件行不行?

那我们把这个地址通过 xswitch 代理转发到本地是不是就可以了?

试了下,遗憾的说:不行

image.png

参考资料:zhuanlan.zhihu.com/p/674981525

原因分析:

  1. 只有在 DevTools 打开时才会加载 SourceMap(性能优化 & 用户并不需要)
  2. DevTools 也是一种扩展,而扩展是无法拦截另一个扩展的请求的(安全性问题)
  3. SourceMap 的加载不能从 Network 中看到而要从 Developer Resources 看到(这也是故意的设计)

基于以上信息,Chrome Extension 主要还是用于折腾 Content 区域,而不是希望你 Hack 浏览器。总之很遗憾,我们不能通过 XSwitch 这样的插件,把 SourceMap 文件的请求地址转发到正确的位置。


解决方案:使用不生成新 map 文件的 SourceMap 类型

目前看我们只能使用不生成新 map 文件sourceMap 类型了。

因为 sourceMap 的类型有很多,以下是不会生成新 map 文件的类型对比:

类型构建速度调试精度推荐环境
eval最快快速开发
eval-cheap-source-map行级别开发环境
eval-cheap-module-source-map较快行级别(含 Loader)开发环境(推荐)
eval-source-map精确精确调试
inline-source-map精确特殊需求
false最快生产环境

AI 推荐我们开发环境用 eval-cheap-module-source-map

image.png

配置如下:

devtool: 'eval-cheap-module-source-map',

验证结果:

✅ 使用 eval-cheap-module-source-map 确实可以定位到源码了!

控制台的 log 信息直接指向了源文件:useProtableProps.tsx:76,而不是编译后的代码。

加了 SourceMap 的结论 🤓

在线上代理的方法上使用默认的 bigfish 的 devtool 值做不到定位源码,我们使用了 eval-cheap-module-source-map,可以在开发环境定位到源码位置,方便调试。


总结 👀

建议大家设置 devtool

  • 开发环境eval-cheap-module-source-map
  • 生产环境false(为了代码安全)
devtool: process.env.NODE_ENV === 'development' ? 'eval-cheap-module-source-map' : false,

又可以开心地 ✍️ 代码了!