如何让调试线上 JS 报错像调试本地源码一样优雅?

网站建设4年前发布
34 0 0

202303060049181389bed87cbd1ec3128858730998c8d7feaedd903,当线上有报错的时候,大家是怎么定位问题的呢?,断点调试么?,但是这时候代码是被压缩过的,变量名都是 a、b、c、d 这种,根本看不出啥来。,如果调试线上报错能像本地开发的时候一样就好了。,其实这是可以做到的,今天就分享下如何优雅的调试线上报错:,首先,我们准备一段 JS 代码:,2023030600475535e5eef948a2fd4d4132011c5708e159213e82291,这是我随便找的一段 JS 代码,里面抛了一个错误。,然后用 webpack 进行编译:,20230306004756c797c2920a29a3cb1a9457cebe63f1c8f5e80c683,在 index.html 里引入构建产物:,2023030600475704d61492039a2a62408463054ae06b9f337c6e729,然后跑个静态服务器 npx http-server .,20230306004758a5062867818a0822538567a7345d184f4edef4152,浏览器访问,就会发现代码确实报错了:,20230306004758f9fad4425f966afb6bf1414ef15654c9dfbe25957,那问题来了,怎么定位错误原因呢?,首先,我们可以使用异常断点,在抛异常的地方断住:,创建一个 vscode 调试配置:,20230306004855b62c1f89306ae3b431f6684d3229ffd4c09924466,勾选 uncaught exceptions,在未被捕获的异常处断住:,20230306004800b29823788bc2b8ff3f8732aaee5dc6e67299a4442,然后启动调试:,2023030600480041d24ed1588b4d46d3426362cd7aa082b68e9c595,你会发现代码在抛异常的地方断住了,这就是异常断点的功能。当你不知道哪里抛的异常的时候,可以用这个。,但现在代码是被压缩过的,看不出啥来:,20230306004856b320c970138a000218d846d917789cfcd97026911,怎么能直接定位到抛异常的源码呢?,这时候就要用到 sourcemap 了,它就是用于把编译后的源码映射回源码的:,2023030600480082adf8a17298d6db72e2045f530c3f4d32ddcc658,首先要生成 sourcemap,这个配置下 webpack 的 devtool 为 hidden-source-map 即可:,20230306004856b6dd19913f6a0359b4b819f66420e615f6546b676,hidden-source-map 的意思是生成 sourcemap 但是不关联。,202303060048010803a9882ecf70fdf7b570d257bf5e705fd0d9791,如果你配成 source-map,代码是关联了 sourcemap 的:,20230306004801194866c02e0857ab02c43029a9b14dc2321f5c237,线上代码不会这样做。,关联 sourcemap 需要在文件末尾加上 //# sourceMappingURL=xxx.js.map 的代码。,但现在这个文件是线上的,不能直接改本地文件。我们可以使用 charles 的断点功能来修改它:,charles 默认不代理 127.0.0.1 的请求,我们要配下 hosts:,20230306004803e92346d03ad4a2756c2209721dba961f0569df407,比如我配了一个 www.guangtest.com 的域名到 127.0.0.1。,试一下:,20230306004803d88a8a02975c76460de301c81b46d736cd86d4295,hosts 配置生效了:,20230306004804b42e3ff60fcd9a8281519936b988fc44c0aab1567,然后我们要让 charles 拦截这个 url 的请求,需要安装一个插件 SwitchyOmega,不过在那之前要指定一个数据目录,也就是浏览器把插件、历史、cookie 等数据保存在哪里:,2023030600485942a7dcc16bffcf6b9da718d8029cf3af8fc2a8956,不指定的话每次调试都会创建一个临时数据目录来跑调试,上次安装的插件就没有了。,chrome 应用商店搜索 switchy omega:,20230306004859f48e81967f5ff2f35c2244a702dc2931f2eba0403,配置下代理服务器,这里我 charles 是在 127.0.0.1:8888 的:,20230306004806c9dd01551279ebbb4e4284ec7d75d3e783a49d170,之后配下 auto switch,让 www.guangtest.com 的请求都走我们刚刚配的代理:,20230306004806f18ea0872e563e04738603a4984e4f6a08476a181,之后点击应用选项。,代理方式设置成 auto switch,也就是根据配置的规则自动切换代理:,20230306004807373bfc4624e6ce3e8544937e4e6ef7cfc86922937,这个网页的代理配成 charles 之后,在 charles 就可以抓到对应的请求了:,20230306004807e1732620172894f514c4343c32934154aa924b493,接下来就是断点修改响应的内容了:,点击 Proxy > Breakpoint Settings,20230306004807d671b41116c077f77ad528bcb96fa40a78a55f380,添加一个对 guangtest.com 的 dist/index.js 响应的断点:,20230306004859b8a9229855bc3f76a7e763f38d0bed6d7cb719299,强制刷下页面,charles 就会断住:,我们可以修改响应的内容,然后点击 execute 来执行修改:,20230306004921161fd64016fa5f48ad9205afb32d948a2fbe55237,我加上了这样一行 sourcemap 的关联:,20230306005228c5773060500c27d7908480a215d88988d1f1df846,在 chrome devtools 里可以看到拿到的响应是被修改过的:,20230306004901b6e70e97179987b1440587a498e47f08f5f385209,异常断点现在直接在源码处断住了:,202303060049024840f5781e283d2166f554536765fc701e4feb962,接下来就可以直接调试源码了,可以通过作用域、调用栈等信息来定位报错原因:,20230306004923e3a906385a491347ae84995bb1ad5b9d741094306,这样我们就完成了直接本地调试线上报错代码对应的源码!,案例代码在:https://github.com/QuarkGluonPlasma/fe-debug-exercize。,通过 sourcemap,我们可以调试线上报错的时候直接对应到本地源码来断点调试。,要让线上代码关联 sourcemap 可以通过 charles 断点修改对应的响应,加上一行 sourceMappingURL=xxx 的注释。,然后在 VSCode Debugger 里加个异常断点,这样就可以在异常处断住。,这样就可以快速定位线上错误的原因了,体验就和本地开发时一样!

© 版权声明

相关文章