1. 前话
我当然相信大佬们能够从敲下第一行代码到部署上线全程无需试运行测试验证一把梭完成并且没有任何bug十分🐂🍺。
但我做不到,所以我需要利用一些前端Debug技能来让我能够顺利地继续搬砖🌚。
开个玩笑哈,人非圣贤孰能犯错。我们日常开发中,Debug时间占比一般不小,如果DDL临近,头又不够硬,从Debug时间中抠出来看来是个成本较低的降低风险的途径
。
下面我简单讲解十分有用的前端Debug技能。
2. 日志调试
前端入门学会的第一个Debug技能是控制台打日志,利用console
打日志是个最简单的Debug技能,我们一般只会用到以下的接口:
console.log('log'); // 控制台打印日志的通用方法
console.info('info'); // 打印信息级别日志
console.debug('debug'); // 打印debug级别日志
console.warn('warn'); // 打印警告级别日志
console.error('error'); // 打印错误级别日志
使用效果如下:
关于console更高级的用法可参考文章 juejin.cn/post/706585…
掌握「日志调试」的基本要求不只是学会了这几个console
打日志的接口,还需理解「打日志」这个动作的「日志规范」。
我们在实际开发中可以在任何地方打日志,但进行无效打日志的行为只会污染控制台的日志,增加关键信息提取难度导致「日志调试」效率低下
。
那么反之,进行「有效打日志」并「降低关键信息提取难度」就能让「日志调试」效率增加,这也是「日志规范」的核心。
「有效打日志」主要是找到「打日志」的地方,这点技巧是「直接在问题点开始逐步往前打日志」,例如卡片标题显示错误,那就在卡片渲染的代码处打印卡片数据,然后往前找卡片数据修改处打印卡片数据,一直找到卡片数据获取处打印卡片数据
。
「降低关键信息提取难度」也就是让输出的日志「明显」,方法因人而异,不限以下几点:
- 增加「前缀」实现输出的日志分类,例如
console.log('__删除XXX__', 'ID = ' + id)
- 功能调试完后删除日志,可利用
husky+lint-staged
禁用提交console
代码
到这里相信读者们也基本掌握「日志调试」了。
3. 断点调试
如果说掌握「日志调试」是入门的前端学者,那么掌握「断点调试」便是合格的前端学者。
「日志调试」简单粗暴,它极其考验前端学者对「打日志」这个动作的规范程度,而且「打日志」也是个花费时间的行为(不断重复写log代码)。
「日志调试」绝大多数的目的是为了观测代码执行过程中的变量数据变化,通过观测执行过程和变量数据排查找出问题点
,那么是不是有具备实现这种目的的更好用的更便捷的替代「日志调试」的Debug技能?
当然有,也就是「断点调试」。「断点调试」相比「日志调试」而言能够「输出」更为详细的信息,让Debug更高效。
使用代码开启断点调试的方式很简单,就一个关键字debugger
,使用示例代码如下:
function doSomething(who) {
debugger;
const word = 'hello ' + who;
console.log(word);
}
doSomething('hello world!');
断点调试依赖调试工具,有很多种,常见的两个分别是「DevTools」和「IDE」,下面简单进行演示。
3.1 DevTools
一般浏览器都自带这个工具,打开调试工具的快捷键挺统一的一般是「command+shift+i」或「ctrl+shift+i」。
开启后的「source」标签,就是代码调试的地方,如下:
我们在打开调试工具的前提下访问使用上面的示例代码的页面,即可在debugger
关键字处暂停代码执行,如下:
在上图我们可以清晰的查询以下信息:
- 左侧面板导航展示了代码文件目录信息
- 中间面板展示了当前代码内容与断点位置信息
- 右侧面板「Scope」展示当前执行上下文的变量信息与「Call Stack」展示完整代码调用栈信息等
- ...
在右侧面板顶部提供相关工具供进行「代码执行」的跳过、步进、进入上下文和返回上下文等操作,如下图:
这里使用的是Chrome的DevTools,关于更详尽的使用方法可查阅官方文档哈,链接在这里 👉 developer.chrome.com/docs/devtoo…
3.2 IDE
前端开发常用的代码编辑器——VSCode同样内置了调试工具。
我们点击Run and Debug
后选择Chrome
,VSCode会自动启动Chrome
访问launch.json配置的页面,并展示当前页面的调试信息,如下:
我们可以看到VSCode的调试工具功能呈现与Chrome DevTools一致,其原理这里就不多说明哈,有兴趣的读者们可以查阅这个文档 👉 zhaomenghuan.js.org/blog/chrome…
4. 线上调试
前端Debug的方式要么是控制台打日志输出代码执行流程的相关信息,要么是调试工具卡断点观测代码执行流程的相关信息。
对于本地应用,这两种Debug的方式可以直接使用。那么对于线上应用,又该怎么使用他们?
思考如何在线上应用进行Debug,首先分析线上应用的特点:线上数据 + 线上代码
。
前端主要从代码侧切入。线上代码一般由本地代码打包构建发布的,因此如何Debug取决于我们是否有对应线上代码版本的本地代码
。
4.1 有对应线上版本的本地代码
有本地代码就好办,本地启动dev开发即可随意打日志或者卡断点,只需要考虑获取到线上数据即可。
现代前端基本是前后分离的开发模式,因此获取线上数据的方式基本通过proxy实现。由于前端的同源策略,因此proxy也有两种:
- 本地域名代理(localhost)
- 线上域名代理
4.1.1 本地域名代理
前端开发常见的开发打包工具webpack可以通过proxy配置,配置示例如下:
module.exports = {
//...
devServer: {
proxy: {
'/api': 'http://localhost:3000',
},
},
};
更多细节请参考官方文档哈 👉 webpack.js.org/configurati…
4.1.2 线上域名代理
相比较本地域名代理,线上域名代理更为灵活。本地域名代理是需要代理的数据接口都需要手动设置,而域名代理我们只需要设置需代理的前端资源。
例如本地webpack启动dev后,提供了本地的访问地址 http://127.0.0.1:3000/index.html ,并且其依赖前端资源的请求路径为 http://127.0.0.1:3000/js/ 。
我们设置域名代理 debugger.com/index.html 到本地地址 http://127.0.0.1:3000/index.html 后,会返回本地的html,其对应会请求路径为 debugger.com/js/ 的前端资源。
这时我们再进行域名代理 debugger.com/js/ 到 http://127.0.0.1:3000/js/ 即可。
线上域名代理的工具有很多,常用的有Charles
和Whistle
等,我这里用Whistle
演示:
-
首先根据文档给的命令
npm install -g whistle
完成安装后执行w2 start
启动代理工具 -
访问
http://127.0.0.1:8899/
代理配置页面进行配置,配置如下图 -
开启设置系统网络代理,设置如下图:
-
访问页面地址 debugger.demo/index.html
关于Whistle更详细的可参考文档 👉 wproxy.org/whistle/
4.2 无对应线上版本的本地代码
无对应线上版本的本地代码的情况较为特殊,因为研发的角色一般会有代码权限。但是如果是测开等辅助排查问题的角色,就会出现无对应线上版本的本地代码的情况。
这时候可使用Chrome的「Source」面板中的「Override」功能即可实现修改线上代码的功能。下面进行实操:
-
开启「Override」功能,如下图:
-
在「Network」找到对应代码的请求,选择「Save for overrides」
-
刷新浏览器,回到「Override」面板中即可找到上一步保存的请求资源进行修改保存
-
再次刷新浏览器,可以看到控制台输出了一条日志
5. 最后
本篇简单讲解了我所了解的场景中可以用到Debug技能,不是十分系统全面,如果有错的话求大佬们指出或者在评论区补充我不知道的其他Debug技能哈。