本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
点击关注公众号,“技术干货__” 及时达!
发布以后,线上报错了,咋办?有没有很恐慌?
每次上线都战战兢兢得生怕出错,又得搞到凌晨一两点,烦死了?这是不是你的现状?作为一名资深程序员,我深知大家得不容易,所以今天奉上一本解决现场问题得法宝。具体如下:
(方法千变万化,没有最好,只有更好,如果大家有更好得办法可以在评论区共同探讨,共同成长,谢谢!)
上线以后,为什么会出现问题?
「问题来源有 2 种:」
现场数据更加复杂,在 uat 测试阶段,由于数据相对比较简单,测试人员得临界值设定得并不准确,导致 bug 没有找出来。
前端代码有问题,在测试的时候没有测试出来,发布以后发现了。
「解决办法:」
❝
「第一:假设这就是后端数据问题,我们需要用一个 chrome 插件: Ajax-intercetion」
❞
下载:直接执行
git clone https://github.com/YGYOOO/ajax-interceptor.git
下载下来以后,直接拉进 chrome 的插件里面就好了,当然你也可以从 chrome 的插件商店里面直接下载,我的 window10 的 chrome 的插件商店被拦截了,进不去,只能从仓库里面获取。不管从哪里获取,拿到就好,无需较真。最后你可以得到如图所示的标志:
把需要拦截的接口地址输入 ajax-interceptor 的 url 的设置里面,然后刷新页面,触发相关功能。
在 chrome 的 devtool 里面的 network 里面找到相关接口的数据,直接 ctrl+A 复制 response
3. 把上面复制好的响应数据放到 ajax-interceptor 的 replace Response with 里面,然后把你觉得异常数据找到,改成合理的数据,然后触发相关功能,你修改后的数据就会展示到页面上。此时就能断定是不是数据问题了。
如果你不会用,没有关系,我为大家找了一个说明视频,大家可以点进去看看:
https://weibo.com/tv/show/1034:4352275389595232?from=old_pc_videoshow
- 经过我们一系列的骚操作,终于发现不是数据问题呀,有没有想死的心都有了?
❝
「第二:现在断定一定是代码的 bug, 可是线上错误指向的是一个压缩文件呀,咋办?」
❞
想解决个 bug,咋就这么难呢?心里喷涌而出的草泥马,算了,不抱怨了,为了早点下班,还是老老实实想一下解决办法,才是正事,你说对不对!我也不兜圈子了看下面。
线上无法调试的根本原因就是没有 suorcemap 呗,说白了就是打包的时候我们配的是 hidden-source-map,而不是 source-map,他们的区别是啥?
首先 hidden-source-map 和 source-map 在打包的时候都会产生一个 .map 文件,而且他们处理后的文件大体是一样的,唯一的区别就是 source-map 处理后的文件下面多了一行代码,如图所示:
我做了个测试代码,一个用 source-map 打包,一个用 hidden-source-map 打包,具体可以看:https://juejin.cn/post/7380222254195572748 结果如下
用 http-server 将他们同时启动
进入页面看看
明显他们的目录访问目录不一样,是不是?解决问题的根本就是把 index.js 和 index.js.map 用 //# sourceMappingURL=index.js.map 关联在一起,他们就能找到源码了,我们就可以欢乐的调试它了,对不对?
❝
方法 1. 利用 chrome 的 add sourcemap 功能,如下:
❞
设置 add sourcemap 的文件的时候,你可以连本地的,反正是对应的. map 文件就好了,如果没有出来,一定是你的地址不对,赶紧改路径吧。
此时 8081 的页面和 8082 的页面就一摸一样了,你是不是就可以开心的调试了呢,一眼看过去就能知道,线上到底是哪一行在报错。
❝
方法 2. 手动映射
❞
- 在项目里面安装 source-map 库
npm i source-map -D
- 在项目里面建立一个 source.js 文件
只需要修改红框的地方即可,操作如下:
const { SourceMapConsumer } = require('source-map')const fs = require('fs')const rawSourceMap = fs.readFileSync('./dist/index.js.map', 'utf-8')// 填入错误信息originalPositionFor('index.js:1:161')function originalPositionFor(errInfo) { const [budleName, line, column] = errInfo.split(':') SourceMapConsumer.with(rawSourceMap, null, (consumer) => { const originalPosition = consumer.originalPositionFor({ line: parseInt(line), column: parseInt(column), }) console.log('bundle name = ', budleName) console.log('original position = ', originalPosition) })}是不是很美丽呀!
❝
方法 3. 用 Charles 代理
❞
其实代理的目的就是对源文件进行拦截,然后在 response 的文件里面加上 //# sourceMappingURL=index.js.map,此时的 url 你可以写线上的 map 文件,也可以指定本地文件对应的. map 文件,也就是说,
可以这样://# sourceMappingURL=index.js.map
- 也可以这样://# sourceMappingURL=http://127.0.0.1/index.js.map
具体如下:
设置断点地址
- 如果此时 Charles 没有工作,很可能是因为你 chrome 的代理插件没有关闭,关闭就可以正常工作了。
其实精髓就是要 index.js 和 index.js.map 连接起来,当然对面的大神们,你们肯定有更好的解决方法,不防在评论区说下,我来给大家补充全面,必经程序的发展本就靠的是大家的集思广益,不是单打独斗!
谢谢!