作为前端开发,如何调试线上代码?

发布以后,线上报错了,咋办?有没有很恐慌?

每次上线都战战兢兢得生怕出错,又得搞到凌晨一两点,烦死了?这是不是你的现状?作为一名资深程序员,我深知大家得不容易,所以今天奉上一本解决现场问题得法宝。具体如下:

(方法千变万化,没有最好,只有更好,如果大家有更好得办法可以在评论区共同探讨,共同成长,谢谢!)

上线以后,为什么会出现问题?

问题来源有2种:

1.现场数据更加复杂,在uat测试阶段,由于数据相对比较简单,测试人员得临界值设定得并不准确,导致bug没有找出来。

2.前端代码有问题,在测试的时候没有测试出来,发布以后发现了。

解决办法:

第一: 假设这就是后端数据问题,我们需要用一个chrome 插件: Ajax-intercetion

下载:直接执行

git clone https://github.com/YGYOOO/ajax-interceptor.git

下载下来以后,直接拉进chrome的插件里面就好了,当然你也可以从chrome 的插件商店里面直接下载,我的window10的chrome的插件商店被拦截了,进不去,只能从仓库里面获取。不管从哪里获取,拿到就好,无需较真。最后你可以得到如图所示的标志:

1.把需要拦截的接口地址输入ajax-interceptor的 url 的设置里面,然后刷新页面,触发相关功能。

2.在chrome的devtool里面的network里面找到相关接口的数据,直接ctrl+A复制response

3.把上面复制好的响应数据放到 ajax-interceptor 的 replace Response with 里面,然后把你觉得异常数据找到,改成合理的数据,然后触发相关功能,你修改后的数据就会展示到页面上。此时就能断定是不是数据问题了。

如果你不会用,没有关系,我为大家找了一个说明视频,大家可以点进去看看:

weibo.com/tv/show/103...

4.经过我们一系列的骚操作,终于发现不是数据问题呀,有没有想死的心都有了?

第二:现在断定一定是代码的bug, 可是线上错误指向的是一个压缩文件呀,咋办?

想解决个bug,咋就这么难呢?心里喷涌而出的草泥马,算了,不抱怨了,为了早点下班,还是老老实实想一下解决办法,才是正事,你说对不对!我也不兜圈子了看下面。

线上无法调试的根本原因就是没有 suorcemap 呗,说白了就是打包的时候我们配的是 hidden-source-map,而不是source-map,他们的区别是啥?

首先 hidden-source-map 和 source-map 在打包的时候都会产生一个 .map 文件,而且他们处理后的文件大体是一样的,唯一的区别就是source-map处理后的文件下面多了一行代码,如图所示:

我做了个测试代码,一个用source-map打包,一个用hidden-source-map打包,具体可以看:juejin.cn/post/738022... 结果如下

用http-server将他们同时启动

进入页面看看

明显他们的目录访问目录不一样,是不是?解决问题的根本就是把index.js和index.js.map用 //# sourceMappingURL=index.js.map关联在一起,他们就能找到源码了,我们就可以欢乐的调试它了,对不对?

方法1.利用chrome的 add sourcemap 功能,如下:

设置add sourcemap的文件的时候,你可以连本地的,反正是对应的.map文件就好了,如果没有出来,一定是你的地址不对,赶紧改路径吧。

此时8081的页面和8082的页面就一摸一样了,你是不是就可以开心的调试了呢,一眼看过去就能知道,线上到底是哪一行在报错。

方法2.手动映射

1.在项目里面安装source-map库

npm i source-map -D

2.在项目里面建立一个source.js文件

只需要修改红框的地方即可,操作如下:

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

  1. 也可以这样://# sourceMappingURL=http://127.0.0.1/index.js.map

具体如下:

设置断点地址

2.如果此时Charles没有工作,很可能是因为你chrome的代理插件没有关闭,关闭就可以正常工作了。

其实精髓就是要index.js和index.js.map连接起来,当然对面的大神们,你们肯定有更好的解决方法,不防在评论区说下,我来给大家补充全面,必经程序的发展本就靠的是大家的集思广益,不是单打独斗!

谢谢!

相关推荐
Myli_ing18 分钟前
考研倒计时-配色+1
前端·javascript·考研
余道各努力,千里自同风21 分钟前
前端 vue 如何区分开发环境
前端·javascript·vue.js
PandaCave28 分钟前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
软件小伟30 分钟前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾1 小时前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧1 小时前
TypeScript 的发展与基本语法
前端·javascript·typescript
hummhumm1 小时前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
asleep7011 小时前
第8章利用CSS制作导航菜单
前端·css
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
幼儿园的小霸王2 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue