如今在移動(dòng)平臺(tái)上,web/hybrid app 不斷向 native app 發(fā)起挑戰(zhàn)。
背景
出于解放生產(chǎn)力和降低成本的考量,越來(lái)越多的團(tuán)隊(duì)開(kāi)始嘗試以 web 技術(shù)來(lái)開(kāi)發(fā)應(yīng)用。
在各移動(dòng)平臺(tái)上,native app 開(kāi)發(fā)都得到了官方的最大支持,工具鏈非常成熟。盡管如此,native app 開(kāi)發(fā)者往往都不喜歡真機(jī)調(diào)試,因?yàn)樗浅YM(fèi)時(shí)。在 webapp 開(kāi)發(fā)這邊,情況更加糟糕。不僅費(fèi)時(shí),由于 webapp 往往要覆蓋多個(gè)平臺(tái),需要在多種設(shè)備上進(jìn)行調(diào)試,這還讓調(diào)試工作變得非常地瑣碎,難以形成通用的方案。
前端開(kāi)發(fā)者在 PC 平臺(tái)上如魚(yú)得水,然而切換到移動(dòng)平臺(tái),則受到掣肘。本文嘗試總結(jié)一些簡(jiǎn)單有效的調(diào)試方案,以滿足不同場(chǎng)景下調(diào)試的需求。
縮小調(diào)試范圍
筆者認(rèn)為移動(dòng)設(shè)備上調(diào)試的需求主要來(lái)自于兩點(diǎn),一是 webapp 使用了(或需要適配)移動(dòng)平臺(tái)上獨(dú)有的特性,例如觸摸事件、虛擬鍵盤遮蓋、移動(dòng)平臺(tái)獨(dú)有的 BOM API 等,二是 webapp 出現(xiàn) PC 瀏覽器上不可復(fù)現(xiàn)的錯(cuò)誤。對(duì)于前者,我們似乎是只能迎難而上,但對(duì)于后者,則可以盡量避免。
出現(xiàn)在 PC 上不可復(fù)現(xiàn)的錯(cuò)誤的主要原因是瀏覽器的兼容性問(wèn)題,其中渲染的問(wèn)題更加突出。得益于 JavaScript 的語(yǔ)言特性和 ES5 廣泛實(shí)現(xiàn),借助 babel 等工具,我們可以將由 ES6 ES7 語(yǔ)法編寫的代碼編譯為 ES5 的,從而避免 JavaScript 上的兼容性問(wèn)題。
不過(guò) CSS 很難甚至是不能被通過(guò)打補(bǔ)?。╬olyfill)和編譯的方式來(lái)達(dá)到完美的兼容性。開(kāi)發(fā)者要對(duì)各目標(biāo)平臺(tái)的 CSS 支持度充分了解,從中選取廣泛支持的特性來(lái)進(jìn)行開(kāi)發(fā)。好在 WebKit 以及衍生品已占據(jù)了移動(dòng)瀏覽器渲染引擎(WebKit 包括用于布局渲染的 WebCore 和執(zhí)行 JavaScript 的 JavaScriptCore 兩個(gè)引擎,本文只取其渲染引擎的含義)的主要份額,使 CSS 特性確定的工作減輕不少。
主要的移動(dòng)平臺(tái)
不可否認(rèn),現(xiàn)如今 iOS 和 Android 系統(tǒng)統(tǒng)治了智能手機(jī)和平板電腦設(shè)備,本文所介紹的調(diào)試方法也僅針對(duì)于這兩個(gè)系統(tǒng)。iOS 上,瀏覽器核心隨系統(tǒng)一直平滑穩(wěn)定地升級(jí),iOS 6 以后支持使用 Mac Safari 來(lái)進(jìn)行調(diào)試。Android 從 4.4 開(kāi)始,其 WebView 基于 Chromium 開(kāi)發(fā),這不僅帶來(lái)了 v8 JavaScript 引擎,還帶來(lái)了可用桌面 Chrome 來(lái)調(diào)試的能力。
除此之外,微信的巨大成功,也讓針對(duì)于微信的 webapp 開(kāi)發(fā)備受重視。在 iOS 上,微信瀏覽器與 Safari 表現(xiàn)一致。在 Android 上,它采用的是騰訊瀏覽服務(wù)(TBS),并非系統(tǒng)提供的 WebView 組件。TBS 的初衷也許是解決在官方版本和衍生版本眾多的 Android 系統(tǒng)上,WebView 表現(xiàn)一致性的問(wèn)題。由于不隨 Android 系統(tǒng)一起升級(jí),在很長(zhǎng)一段時(shí)間里,TBS 的 Webkit 版本都落后于系統(tǒng)的 WebView,導(dǎo)致微信常被調(diào)侃為“移動(dòng)端的IE 6”。好在今年 3 月基于 Blink 打造的 TBS 2.0 終于發(fā)布,使其支持更新的 CSS 特性。
調(diào)試工具
本文僅介紹可以免費(fèi)下載和使用的工具。
1、weinre 與 jsconsole
weinre (WEb INspector REmote) 與 jsconsole 是原理上相似的工具。weinre 復(fù)用了 WebKit 的 Web Inspector 的界面代碼,有 Safari 和 Chrome 調(diào)試器經(jīng)驗(yàn)的開(kāi)發(fā)者會(huì)對(duì)此非常熟悉。jsconsole 是一個(gè) JavaScript 的 web 控制臺(tái),它能接管控制臺(tái)的日志輸出,也能響應(yīng)調(diào)試服務(wù)器發(fā)出的求值命令(通過(guò) Server-Send Event 發(fā)出),將日志和求值結(jié)果通過(guò) xhr 發(fā)送到服務(wù)器。jsconsole 功能雖然更少,但官方提供了一個(gè)開(kāi)箱即用的線上應(yīng)用,http://jsconsole.com/,無(wú)需安裝任何軟件即可開(kāi)始調(diào)試。兩者的調(diào)試功能都是由 JavaScript 編寫,都必須把調(diào)試服務(wù)腳本插入目標(biāo)頁(yè)面,使其難以用于線上產(chǎn)品的調(diào)試。并且由于運(yùn)行在瀏覽器沙盒中,其提供調(diào)試能力受到了較大的限制,例如無(wú)法查看 httponly 屬性的 cookie,和非 xhr 的請(qǐng)求。
2、微信 Web 調(diào)試工具與 spy-debugger
這兩者也是類似的工具,都是基于 weinre 開(kāi)發(fā)的。設(shè)備連接調(diào)試工具提供的代理后訪問(wèn)目標(biāo)網(wǎng)頁(yè),weinre 的調(diào)試腳本會(huì)被自動(dòng)注入到 HTML 頁(yè)面,從而免除了手動(dòng)注入的麻煩。相比于 weinre 僅能查看 HTTP xhr 請(qǐng)求,利用代理,微信 Web 調(diào)試工具提供了查看所有 HTTP 請(qǐng)求的能力。不過(guò)由于沒(méi)有實(shí)現(xiàn) HTTPS 中間人,無(wú)法查看 HTTPS 請(qǐng)求。 spy-debugger 在這些功能之上提供了查看 HTTPS 請(qǐng)求的功能。值得一提的是,微信 Web 調(diào)試工具額外提供了調(diào)試微信 JSSDK 的能力,不過(guò)調(diào)試對(duì)象并不是真機(jī),需是其提供的瀏覽器窗口。
3、Safari 與 Chrome
使用 PC 瀏覽器來(lái)調(diào)試對(duì)應(yīng)的移動(dòng)瀏覽器,你將擁有最佳的調(diào)試體驗(yàn)。WebKit 家族的 PC 瀏覽器都有非常強(qiáng)大的調(diào)試工具,其調(diào)試移動(dòng)設(shè)備的體驗(yàn)幾乎與調(diào)試桌面網(wǎng)頁(yè)無(wú)異。Opera 自從將渲染核心從 Presto 切換到 Blink 之后,自家用于調(diào)試 Opera Mobile 的 Dragonfly 也被移除了,可見(jiàn) Opera 對(duì) Webkit 調(diào)試工具也是滿意的(汗)。
Mac Safari 調(diào)試 iOS Safari 和 UIWebView 只需經(jīng)過(guò)簡(jiǎn)單的設(shè)置。首先在 iOS 設(shè)備上啟用 Safari 的 Web 檢查器功能(設(shè)置>Safari>高級(jí)>Web 檢查器),再通過(guò) USB 線纜連接到 Mac,然后就能在 Mac Safari 的“開(kāi)發(fā)”菜單中選中該設(shè)備來(lái)進(jìn)行調(diào)試。如果沒(méi)有找到“開(kāi)發(fā)”菜單,則需要在 Safari 偏好設(shè)置中啟用調(diào)試功能。調(diào)試 UIWebView 的步驟是一樣的,但是要求 app 在該 Mac 設(shè)備上能被調(diào)試,也就是說(shuō)第三方開(kāi)發(fā)者是不能直接調(diào)試微信的 UIWebView 的。
Chrome 調(diào)試 Chrome for Android 和基于 Chromium 的 WebView 的詳情可以在https://developers.google.com/web/tools/chrome-devtools/debug/remote-debugging/remote-debugging找到。值得一提的是,Chrome 調(diào)試支持 Screencast 功能,能夠?qū)⒁苿?dòng)設(shè)備上的 Web 視圖投射到 Chrome 調(diào)試工具中,不過(guò)這回降低 webapp 的性能表現(xiàn)。
使用 Chrome 來(lái)調(diào)試 iOS 設(shè)備也是可行的。利用 google 開(kāi)發(fā)的 ios-webkit-debug-proxy,把 Safari 的遠(yuǎn)程調(diào)試協(xié)議代理到 Chrome DevTools 上,可以由 DevTools 接管幾乎所有的調(diào)試功能。
Webkit 遠(yuǎn)程調(diào)試協(xié)議
Webkit
Safari 和 Chrome 在移動(dòng)平臺(tái)上強(qiáng)大的調(diào)試能力源自 Webkit 的遠(yuǎn)程調(diào)試協(xié)議(remote debugging protocol)。Webkit 的遠(yuǎn)程調(diào)試協(xié)議是 Webkit 在 2012 年引入的,目前所有 Webkit 內(nèi)核的瀏覽器都支持這一特性。DevTools 通過(guò)遠(yuǎn)程調(diào)試協(xié)議與目標(biāo)頁(yè)面相連,可以獲取到 Webkit 內(nèi)核提供的調(diào)試信息,這些信息遠(yuǎn)比 weinre 等在瀏覽器沙盒中獲取的要準(zhǔn)確和豐富。Webkit 遠(yuǎn)程調(diào)試協(xié)議與 Chrome DevTools 都是開(kāi)放的,這讓 ios-webkit-debug-proxy, React DevTools 和 vue-devtools 等強(qiáng)大且富有想象力的調(diào)試工具能成為現(xiàn)實(shí)。得益于協(xié)議的開(kāi)放性,其他廠商也對(duì) Webkit 調(diào)試表現(xiàn)出積極的興趣。Firefox 宣布了用于調(diào)試 Webkit 內(nèi)核瀏覽器的 Valence,不過(guò)目前仍處于技術(shù)預(yù)覽版。
Fiddler
Fiddler 是可以運(yùn)行在 Mac,Linux 和 Windows 上的一個(gè)用于 web 調(diào)試的代理軟件??梢杂脕?lái)查看 HTTP API 訪問(wèn),AMD 腳本加載,緩存命中等。Fiddler 有豐富的調(diào)試功能,其中支持 HTTPS 捕獲和篡改請(qǐng)求響應(yīng)對(duì)移動(dòng)端調(diào)試十分有用。
使用 HTTPS 捕獲功能需要在移動(dòng)設(shè)備上安裝 Fiddler 提供的證書,各移動(dòng)平臺(tái)的設(shè)置方法可在http://docs.telerik.com/fiddler/configure-fiddler/tasks/configurefiddler找到。有時(shí)我們需要替換線上產(chǎn)品的某個(gè) js 文件來(lái)定位問(wèn)題,或者偽造 session 來(lái)模擬使用場(chǎng)景,F(xiàn)iddler 的篡改功能就能派上用場(chǎng),具體的使用細(xì)節(jié)可以在http://docs.telerik.com/fiddler/KnowledgeBase/FiddlerScript/ModifyRequestOrResponse找到。
結(jié)論
調(diào)試運(yùn)行 iOS >= 6 和 Android >= 4.4 的設(shè)備,優(yōu)先采用 Safari 或 Chrome 進(jìn)行調(diào)試。其余情況,可采用 weinre 及其衍生工具和 jsconsole。Fiddler 可作為這些方案的有效補(bǔ)充。
參考資料:
http://javascript.ruanyifeng.com/bom/mobile.html
https://developer.chrome.com/multidevice/webview/overview
http://bbs.mb.qq.com/thread-1128359-1-1.html
https://github.com/wuchangming/spy-debugger
https://github.com/google/ios-webkit-debug-proxy
http://people.apache.org/~pmuellr/weinre/docs/latest/Home.html
https://developers.google.com/web/tools/chrome-devtools/debug/remote-debugging/remote-debugging
http://docs.telerik.com/fiddler/configure-fiddler/tasks/configurefiddler
http://docs.telerik.com/fiddler/KnowledgeBase/FiddlerScript/ModifyRequestOrResponse
http://taobaofed.org/blog/2015/11/20/webkit-remote-debug-test/
https://trac.webkit.org/wiki/WebInspector
https://facebook.github.io/react/blog/2014/01/02/react-chrome-developer-tools.html
https://github.com/vuejs/vue-devtools
https://developer.mozilla.org/en-US/docs/Tools/Valence
http://moduscreate.com/enable-remote-web-inspector-in-ios-6/
本文作者:陳倬(點(diǎn)融黑幫),目前就職于點(diǎn)融網(wǎng)成都前端團(tuán)隊(duì),主要負(fù)責(zé)內(nèi)部 webapp 的開(kāi)發(fā),喜歡 Vue.js 。