不是我的bug(react-native-network-logger)

259 阅读7分钟

1. 感悟

作为大前端,不知道各位有没有这样的感悟,作为前端很容易背锅,因为前端是用户,也是领导老板第一时间看到的,什么不好的表现都体现在界面上,比如没有数据显示呀,数据突然不按事先规定的返回导致的界面显示错误呀啥的,都第一时间找我们前端,我们不得不抓包来看接口,看看是不是没有返回数据或者是不是接口报错了啥的。如果你做的是 web 端,可以很方便的打开控制台来查看接口返回的数据,但是如果你跟我一样开发的 react-native ,那么你就不那么幸运了,因为在 release 下查看接口是不方便的,虽然是可以使用 charles 来抓包,但是抓 https 还需要装证书,不是很方便。

在开发过程中,过去我们可以使用 react-native-debugger 来调试状态管理,网络请求,查看日志,但是这个还需要开启 debug 才能使用,而一些插件是不支持的,比如动画库 react-native-reanimated ;除了这个以外还有 flipper 可以选择,而且这个不需要开启 debug 模式就能愉快的调试了。但是在 release 下除了 charles 目前没有更好的选择了。

我在工作中发现由于不方便查看 app 的网络日志,经常出现 bug 是我的,而且测试在测试过程中一般不会经常使用 charles ,因为我们测试有时候都是使用自己的手机测试,所以有时候就会忘记;但是有时候出现错误可能只会出现一两次,导致错过了问题,就一直把 bug 挂在我的身上,只不过 bug 被标记为偶现。基于上面的原因我开发了一个在测试测试过程中能方便查看日志的软件,目前日志的查看已经完全可以用了,网络除了日志太多会卡顿以外也能使用了,这部分功能我也还在完善中;欢迎有需求的同行们使用起来,同时帮我点一个 star ,如果你在使用过程中遇到问题欢迎提 issue ,或者你希望增加什么功能也可以提,当然你也可以跟我一起将这个软件弄好。这是我的项目地址:github.com/wutiange/lo…

我在编写这个软件的过程中也在不断地借鉴别人的优点,或者为了解决一些问题不断地查找,寻找优秀的库,然后学习后就可以集成到我的软件中。其中 react-native-network-logger 这个库就是我在这个过程中发现的,我试用了一下发现非常棒,于是我欣赏了源码,发现网络的处理部分比我采用的方法要好很多,我的网络部分到时候也会采用其思路进行实现。

2. 试用

这个库要想使用起来很轻松,首先安装:

yarn add react-native-network-logger

然后在程序的入口处调用下面的代码即可:

import { startNetworkLogging } from 'react-native-network-logger';

startNetworkLogging();

这样你的网络日志就被记录,接下来就是将抓到的日志显示出来,这个库内置了网络现实的界面,我们只需要在要显示的地方渲染出来就可以了。

import NetworkLogger from 'react-native-network-logger';

const MyScreen = () => <NetworkLogger />;

这个默认是会占据布局的,如果你不希望那你就使用 View 包裹一下,然后采用绝对定义;或者采用 Modal 来显示。

大部分情况下上面的代码就满足你的需求,如果你还有一些其他特别是需求,那么可以查阅这个库的文档,其中都非常详细的记录着;比如支持最大条数,过滤网址,对请求排序等等。

3. 原理

这个库是纯 js 库,主要是利用 react-native 官方暴露的 XHRInterceptor 方法来实现的,所以要想了解这个库只需要了解这个的用法就可以了。这个库就是 XMLHttpRequest 的拦截器,如果你还不会 XMLHttpRequest ,那么可以去 XMLHttpRequest 这里学习学习;虽然 react-nativeXMLHttpRequestweb 端的不是同一套代码,但是 react-native 官方按照标准实现了这个类,这也是为啥 axios 能在 react-native 使用原因;本身 react-native 中的 fetch 也是基于 XMLHttpRequest 实现的。

我们可以使用 XHRInterceptor 来监听网络中的任何行为,比如:

  1. XMLHttpRequest.open() 对应的就是 XHRInterceptor.setOpenCallback(callback) ;
  2. XMLHttpRequest.send() 对应的就是 XHRInterceptor.setSendCallback(callback)
  3. XMLHttpRequest.setRequestHeader() 对应的就是 setRequestHeaderCallback(callback)
  4. 请求完成的事件就是 setResponseCallback(callback)

等等还有其他的。具体参阅 XHRInterceptor 源码。而 react-native-network-logger 的核心文件是 Logger.ts ,这个文件主要就是对相同的请求放到一块同时对拦截到的请求根据用户的配置进行筛选排序。

4. 进一步思考

为啥我们需要这个库 react-native-network-logger ,简单点讲是为了查看网络日志,但是细想为啥会有这样的需求;我们在调试 h5 时会使用 vConsole ,因为这些可以方便我们查看日志,方便排查错误,特别是一些兼容性的问题,在多年前我面对 webview 的调试一筹莫展,因为我们编写 react-native 就难免跟 webview 打交道,但是 webview 的日志不是很方便看,特别是 react-native 中的 webview ,这时有像 vConsole 的工具可以使用,我们就能知道是不是报错了。还有一个调试 webview 的方法就是使用 chrome://inspect/#devices 来调试,只要插上 usb 线就可以使用 chrome 调试界面了。

回到我的标题,前端最容易背 bug ,就是因为我们看得见,而后端是看不见的,如果你不是程序员,程序出现任何问题你可能都觉得是写界面的人的问题,即便你不认为是,你也会优先找写界面的人。其实真正属于前端的 bug 是很少的,特别是你的界面逻辑很少的情况下,那如果真的每一次都是经过前端排查一遍,那效率是很低的,而且由于看不见数据,就没有证据证明是谁的问题,只要证明不了是谁的问题这个时候就一定会是前端的问题;再加上后端更新比我们前端更方便,所以想想就可怕,不管是从担责任的角度还是尽早找到 bug 的角度,有这个 debugger 的工具都是事半功倍,自从我开发了那个日志工具后,我就给公司大部分人都安装上了,然后他测试的时候就一直开着工具,出现问题即便操作的人看不懂我过去看一看日志就找出问题所在了,这样就不需要再让对方在我的开发手机上复现了;对那些难以复现的问题更是如此。

开发的时间越久我们越是发现沟通的成本很大,不光是指跟产品和测试沟通;更是指我们前端跟设备端,跟后端的沟通成本很大,特别是你们公司还不是很规范,那么这个过程的成本是巨大的,比如看数据格式不是先看文档,而是先调用接口看返回数据。而且即便真的有文档,你看的时机不同结果也就不同,所以你最后还是会沦为看接口返回;所以这个过程要想真的做好是很难的,很多因素影响,比如由于产品需求定义不明确,朝令夕改;或者由于技术方案选择失误导致更换实现方案等等最后都可能导致交互的数据发生变化,我说的都还只是冰山一角。但又想过来,有时候你不能从能力上批判一个人,因为需求本身就是变化的,技术方案有时候也不可能完全考虑到所有的需求,同样产品需求也不可能完全不变,因为市场是变化的。那既然变化是难免的,那么我们就从变化中找到提高效率的办法,其中收集日志就是其中之一。既然沟通是一个很大的成本,那么记录沟通的过程就显得很重要,只有记录了我们才能更容易发现沟通过程中的问题。