展示:console.log/info/warn/error
(alert
)
(Value below was evaluated just now.)
console
引用类型的数据,在点击开来查看的这个时刻才去取引用类型的快照(意味着可以console之后再修改展示内容),打开之后不再关联。
更好的展示:
console.groupCollapsed/group
至console.groupEnd
console.table
console.trace
console.time
至console.timeEnd
监控告警
根据错误日志,找到错误根源。
还原错误源代码、还原错误堆栈
SourceMap。
错误触发所在的UA(系统版本、app版本、浏览器版本)
判断是否是某些特定版本系统,如:低版本Android等。
- 遵循devtools-protocol协议的应用都拥有打开Chrome的DevTools进行调试的能力。
- 遵循JavaScriptCore协议的应用都拥有打开Safari的
开发
进行调试的能力。
debugger
、配合SourceMap,通过Call Stack查看调用栈)。Node.js
通过Chrome的 <chrome://inspect/#devices>,监听Node.js程序运行node --inspect 文件
,可使用debugger
等进行断点调试、console
打印等。
针对已开启调试功能的APP连接对应的调试工具:
最佳方式:连接上电脑后借助 Chrome的DevTools(遵循devtools-protocol) 或 Safari的
开发
(遵循JavaScriptCore)。
Android
PC端的Chrome的Remote devices(<chrome://inspect/#devices>)可以调试Android已开启调试功能的APP的WebView。
Remote devices需要能够访问google,否则首次打开inspect页面会404。会自动联网更新相关SDK:控制台界面修复(低端机原本乱码,更新后会正常显示)、渲染器升级(低端机一开始不支持的CSS特性,更新后会支持)。
Android已开启调试功能的APP:
若PC端的Chrome识别不到手机WebView,可以下载Android Debug Bridge (adb)(macOS可以用brew安装:
brew cask install android-platform-tools
)并运行(进入文件夹后运行adb.exe devices
或adb devices
连接手机设备)。
若APP没有开启调试功能,只能连接电脑的logcat看日志。
iOS
macOS的Safari的开发
可以调试iOS已开启调试功能的APP的WebView。
iOS已开启调试功能的APP:
对于未开启调试功能的APP,内部的WebView可以进行元素样式、命令行调试(e.g. weiner、vConsole),但无法进行debugger调试。e.g. 微信APP内部的WebView,无法进行debugger调试(
spy-debugger、ios-webkit-debug-proxy均不能),只能作为APP的开发者或使用越狱版微信进行调试。
若APP没有开启调试功能,只能连接Xcode看日志。
使用抓包工具查看请求、Map请求,如:Charles、whistle。
Tips:
- 若命中强缓存(本地缓存),则不会发起请求,所以抓包工具也无法抓到命中强缓存(本地缓存)的资源,也就无法对这些资源进行代理操作。
- (高版本Android默认禁止了明文通道、只信任系统CA证书,)客户端开发需要设置APP能够信任自定义CA证书,才能正常抓包。
iOS用Xcode模拟器运行客户端调试APP(Xcode文档:https://developer.apple.com/documentation/xcode)
Android用真机安装APK调试APP(Android Studio文档:https://developer.android.com/studio/intro)
Android(真机)
adb端口代理
adb reverse tcp:「手机端口号」 tcp:「PC端口号」
手机访问「手机端口号」的流量都会转发到PC的「PC端口号」。
adb forward tcp:「PC端口号」 tcp:「手机端口号」
PC访问「PC端口号」的流量都会转发到手机的「手机端口号」。
debugger
JS日志、断点:
chrome://inspect/#devices
设置Targetlocalhost:「PC端口号」
客户端日志:
adb logcat
或:adb shell
之后logcat | grep 「筛选内容」
。
Android Studio的logcat(需要安装SDK)
元素查看
Android Studio的Layout Inspector
结束选择Stop inspector。
性能调试
Android Studio编译APK(Android Application Package)
改动代码 -> Make -> Run -> target获得APK
Make === Build === 编译。APK路径:app/build/outputs/apk/debug/app-debug.apk。
Make一次后已生成编译好的文件,之后都可以直接Run 「项目名」(不需要再Make)
可以仅对改动的地方进行「增量」编译后运行:
Make Module 「模块名」
Make Project
Run需要有target(真机或模拟器)
若出问题,可以考虑:
若报错的某些SDK,但又明确SDK目录有这些文件夹,则可能之前先安装后删除时没有删除干净,导致文件夹存在,系统判定已装但使用报错。
根据错误提示,尝试去SDK安装目录(如:~/Library/Android/sdk/
),手动删除导致问题的某SDK文件夹,让其能够重新下载同步。
iOS(Simulator)
Xcode的Parallelization并行化设置为最大,增加编译效率。Xcode无法安装任何应用,只能安装代码编译上去的应用。
Xcode模拟器构建运行App
Run(command + R) 或 Run Without Building(command + control + R)
.ipa(iPhone application archive)文件仅支持真机;.app文件支持模拟器和真机。
debugger
JS日志、断点:
Safari的网页检查器(自动显示JSContext、自动暂停连接到JSContext)
调试H5页面时要关闭「️自动显示JSContext的网页检查器」,无效且影响页面切换性能。
客户端日志:
Xcode底部
元素查看
Xcode的Debug View Hierarchy
查看时会阻塞进程。结束点击Continue program excution。
性能调试
Simulator
若模拟器内
command+其他
的快捷键无效,则尝试先按option+其他
再按command+其他
会有效。
代理到whistle(端口8899,或其他任意代理)
Simulator内安装whistle证书
Safari输入127.0.0.1:8899
,安装、同意证书。
Simulator设置http请求发送到8899
方法二:利用Proxifier V2(可代理PC所有应用到指定地址和端口)
关注顶部的操作
软键盘开启:
Simulator -> I/O -> Keyboard -> 取消选择:Connect Hardware Keyboard
取消连接到硬件keyboard,这样就取消了连接到电脑的键盘,而使用iOS模拟器自己的键盘。
模拟定位:
Simulator -> Features -> Location
复制-粘贴:
Simulator -> Edit -> Automatically Sync Pasteboard
若失败,则:Copy/Paste not working in XCode 13 Simulators with M1 Macbook Pro(非M1亲测也可)。
Android真机调试:
开发人员选项
来自:配置设备上的开发者选项。
打开方便调试
可选
连接着的手机,无法识别,
Discover USB devices
可以减少断连手机。其他策略
上线的页面中藏着某些「后门」调试(如:隐蔽操作开启console
)
可以在URL中判断某些特定的search
值,以开启调试模式。
e.g.
xxx?debug=1
开启
WAP端可以用一些隐蔽的手势触发log信息展示。
e.g.
```javascript let consolelogId = 0 function wapConsole () { if (event.touches.length >= 4) { // 4个触发点以上 consolelogId += 1 if (consolelogId >= 2) { // 2次以上触发 // 展示隐藏的调试信息 const newScript = document.createElement('script') const appendPlace = document.getElementsByTagName('body')[0] || document.getElementsByTagName('head')[0] newScript.onload = function () { // 只能保证加载完成,但不能判断是否执行 eruda.init() // new VConsole() newScript.onload = null } // onerror表示加载失败 newScript.src = '//unpkg.com/eruda' // '//unpkg.com/vconsole' appendPlace.appendChild(newScript) document.removeEventListener('touchstart', wapConsole, false) } } } document.addEventListener('touchstart', wapConsole, false) ```
Chrome的DevTools文档:https://developer.chrome.com/docs/devtools/overview/
$0
、$1
、$2
、$3
、$4
返回在Elements面板中选中的 当前、上1个、上2个、上3个、上4个节点。
monitor(「函数名」)
、unmonitor(「函数名」)
观察/取消观察某函数,若观察的函数被调用,则输出函数名和参数。
monitorEvents(「DOM」[, 事件名或事件名数组])
、unmonitorEvents(「DOM」[, 事件名或事件名数组])
Safari相同。
观察/取消观察DOM的事件,若观察的DOM事件被触发,则输出事件名、事件对象。
copy(「值或变量名」)
Safari相同。
拷贝一个对象(DOM也可)为字符串表示方式到系统剪切板。
getEventListeners(「DOM」)
Safari相同。
获取注册到一个DOM上的所有事件监听器。