手机调试利器 - 总结与实践

@fwon 2016-05-21 15:27:05发表于 fwon/blog

一些调试工具

说起手机端调试,相比大家都不陌生。

由于手机浏览器没有像PC端浏览器一样有开发调试工具,所以一般手机端的调试都要借助于电脑,现在的调试方式通常有以下几种。

  1. 直接在chrome, firefox等开启模拟器调试
    简单直接,还能模拟网络等,但是仍然无法100%还原手机的真实情况。
  2. 实现一套pc调试面板
    采用这种实现方式有weinre,weinre很早前就比较流行了,使用也比较广泛,运行后会在PC上生成一个像chrome开发工具一样的调试器。能对手机进行远程调试,能操作DOM,打印console输出等。
  3. 通过与远程服务器通信,传递打印消息
    比较流行的有jsconsole,它是在远程部署一个服务器,并生成一个具有唯一标识远程文件给本地调用,本地嵌入该文件后,会在页面上生成一个iframe。通过使用postMessage实现本地与远程调试器的通信。调试的时候可以在远程页面上打印console输出。
  4. 直接将调试信息输出在手机屏幕上
    这种实现方式的也比较多,如js-mobile-console,还有微信的vConsole
  5. 安装各种虚拟机sdk, 在电脑上进行手机调试。
  6. chrome上可以设置远程调试功能,手机使用数据线连接电脑。

优缺点分析

以上这些方法在开发中都尝试过了,各有各的优缺点。

  1. chrome模拟器最为方便,然而模拟器和真是机器还是经常有很多差别的,有时候模拟器运行正常,到真机上就懵逼了。
  2. weinre安装和开启会比较繁琐,PC和手机同时调试的时候需要关注两个调试面板,效率不是很高。
  3. jsconsole这种调试没有提供DOM的操作,只是单纯的进行log输出,然而实际使用中需要使用到DOM操作的比较少,大部分的工作都可以通过模拟器来完成,如果手机上显示稍有不同,只要更改代码,自动刷新查看效果就可以了,真正需要的功能是打印出手机上值。而个人认为jsconsole的缺点就是需要跟远程地址通信,打印速度受到一定影响,在需要测试scroll等的输出时会打印不及时。而且需要另外开启一个tab查看打印信息。
  4. 直接将信息输出到屏幕上应该是最简单粗暴的方法,但是需要在手机这么小的屏幕上打印信息,信息会挡住操作元素不说,就是查看复杂数据结构的log也很不方便。个人认为这种不太实用。
  5. 电脑上安装手机虚拟机就不多说了,虽能比较真实模拟手机,但是安装繁琐,操作不方便,无法模拟真实的手势操作。
  6. chrome的远程调试弊端也比较明显,导致使用的人并不多。首先是需要连接数据线,其次是设置比较繁琐,而且还限制了android手机。对于IOS的调试则可能要使用Safari的另一套工具。

一般开发中手机的远程调试不是强需求,除非遇到一些手机上的奇葩bug, 比如浏览器引擎对js的实现方式差异,需要打印真实数据,chrome模拟器都可以解决90%的问题。

但是每当遇到这种问题时,我还是会纠结到底使用哪个工具来做调试。原因很简单,我只是想把手机的信息打印到电脑浏览器上,不想打断PC端的调试,不想开启其他附属功能,仅此而已。因此我自己写了一个手机端打印的命令行工具,功能和实现都比较简单。

小而简单的工具 m-console

m-console 灵感来自livereload,livereload的实现应该是通过WebSocket来进行浏览器跟本地的通信。页面中引入一个客户端版本的livereload.js文件,当本地文件修改被watch进程捕获后,会通知livereload的WebSocket服务器,服务器通知客户端文件已更新,浏览器中引入的文件监听到这次更新,则调用window.location.reload实现浏览器刷新。

那么,显然我们能用Websocket来做远程调试,通知手机端通知浏览器打印log。

原理如下:

  1. 开启一个WebSocket作为服务端。
  2. 在浏览器中引入一个脚本用于连接服务端。
  3. 当判断在手机端访问时,重写console方法,发送log到服务端。
  4. 服务端接收到手机发来的消息,把消息广播给所有客户端。
  5. 客户端监听服务端,将消息打印出来。

具体实现可查看代码,该命令行工具有以下特点:

  1. 直接将信息打印到PC浏览器的调试工具的console面板,不必开启另外的打印页面。
  2. 支持所有console类型,支持js报错打印。
  3. 本地开启服务器,打印速度比较快。
  4. 使用简单,只需一个命令。