線上頁面有 bug 了,或者需要修改或增加某項功能時,傳統的開發/除錯方法如下:
1.在本地搭建一套完整的開發環境,前後端程式碼甚至資料庫等全在本機。想修改啥就修改啥,修改驗證好了釋出上線即可。好處是全盤控制非常強大,壞處是環境越複雜越麻煩。當本地與線上存在差異時,有些 bug 甚至無法重現。對於雲時代的前端開發攻城師來說,這種方式太笨重了。
2.本地僅儲存前端程式碼,修改後,提交到測試環境驗證。這種方式無需搭建本地環境,但除錯起來麻煩,遇到棘手的 bug 時,很可能需要反覆 修改程式碼 -> 提交程式碼 -> 驗證功能 -> 再次修改。雖然可以通過指令碼部分實現自動化,但還是不夠方便。
3.將線上頁面儲存到本地,直接修改頁面中的 css/js 引用。這招非常簡明快捷,在某些場合下的確是上上之選。但壞處也很明顯,頁面稍微複雜一點,就有可能失靈。
為了過上快樂幸福的生活,愛折騰的攻城師們想出了一個好點子:線上本地除錯。
名詞解釋
線上本地除錯是指:
1.線上是指環境。環境是線上的,包括資料請求、cookie 等等,不是高仿,是貨真價實的正品。
2.本地是指前端程式碼在本地,包括 js/css 等靜態資源。
3.除錯是指修改原生程式碼 + 重新整理頁面即可看到效果。
基本原理
很多事情,沒有做不到,只有想不到。一旦開始追求美好的除錯生活,立刻就能發現原理非常簡單:
只要能將需要除錯的程式碼對映到本地即可。
對前端來說,需要除錯的程式碼一般是 js/css 檔案。
html 程式碼有時也需要修改,可以搭建本地環境或用 Fiddler 等工具來實現,這篇部落格裡就不多說了。
我們將關注點聚焦到 js/css 檔案的本地對映。
方式一:客戶端工具
在 Windows 系統下,可以用大名鼎鼎的 Fiddler 來實現:AutoResponder Reference . 阿里巴巴中文站 UED 部落格有圖文教程:使用 Fiddler 提高前端工作效率
在 Mac 系統下,也有類似的工具:Charles .
客戶端工具的好處是靈活,想對映什麼就對映什麼,想對映到哪就對映到哪。
壞處是要安裝軟體。在雲時代,安裝客戶端軟體顯得太 out 啦。更惱人的是,Fiddler 依賴 Microsoft .NET Framework. Charles 更不用說了,是收費的。
方式二:服務端代理
比如在淘寶,可以先讓所有攻城師都修改 hosts:
1 |
10.1.2.3 a.tbcdn.cn |
使得 js/css 檔案都通過內部代理伺服器來訪問。既然是內部伺服器,就可以進一步通過 samba 等服務 mount 到本地。
好處是可定製性高,可以實現本地、測試、預發和線上等環境的自由切換等等功能。
壞處是對內網環境有依賴,在外網使用時,需要開啟 VPN 軟體。其次,要從伺服器端代理回本機目錄時,要通過
HFS 等客戶端軟體來實現,有點小麻煩。還有一個小缺陷是,當同時使用的人數過多時,伺服器的效能和穩定性很重要。一旦出故障,攻城師就只能看美女了。
無論如何,淘寶聰明的攻城師們已實現了一個內部方案:UCool. 非常贊非常好用,內部人士不容錯過。
方式三:利用虛擬主機與檔案重寫
作為攻城師,工作電腦上開一個 web 服務是家常便飯。假設我們使用的是老牌的 apache. 通過 Virtual Host 和 Rewrite Module 就可以實現本地對映。下面以淘寶為例來說明。
淘寶的 js/css 檔案存放在 cdn 上,有兩個域名:a.tbcdn.cn
和 assets.taobaocdn.com
. 絕大部分線上頁面使用的是 a.tbcdn.cn
. 因此我們可以繫結 a.tbcdn.cn
到本地,同時保持 assets.taobaocdn.com
依舊指向線上:
1 |
1 |
127.0.0.1 |
1 |
a.tbcdn.cn |
1 |
接著修改 apache 的配置檔案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<VirtualHost *:80> DocumentRoot "/Users/lifesinger/Sites/svn/assets/" ServerName a.tbcdn.cn RewriteEngine On # # handle combo url "/??path/to/a.js,path/to/b.js" # RewriteCond %{QUERY_STRING} ^\?.*\.(?:js|css)(?:,|$) [NC] RewriteRule ^/.*$ /combo.php [QSA,L,NS,NC] # # redirect to online version when the requested file does not exist in local file system. # RewriteCond /Users/lifesinger/Sites/svn/assets/%{REQUEST_FILENAME} !-F RewriteRule ^/(.+)$ http://assets.taobaocdn.com/$1 [QSA,P,L,NC] </VirtualHost> |
combo.php
的內容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
$LOCAL_ROOT = "/Users/lifesinger/Sites/svn/assets"; $REAL_CDN = "http://assets.taobaocdn.com"; $parts = explode("??", $_SERVER[REQUEST_URI]); $base = $parts[0]; $files = explode(",", $parts[1]); if (strpos($files[0], ".js")) { header("Content-type: application/x-javascript"); } else { header("Content-type: text/css"); } foreach($files as $file) { $url = $base.$file; $root = $REAL_CDN; if(file_exists($LOCAL_ROOT.$url)) { echo "/* fetched from local file system */n"; $root = $LOCAL_ROOT; } echo file_get_contents($root.$url); } |
這樣,要除錯某個檔案時,僅需要在本地 assets
目錄下,按照線上的目錄結構,放上需要修改的檔案即可。本地沒有的檔案,會依舊訪問線上。
這種方式很靈活強大,稍微修改修改,對絕大部分專案都適用。缺點是稍有門檻,要自己配置。對於愛折騰的攻城師來說,強烈推薦這種方式。
方式四:基於 seajs 的本地對映
如果一個頁面是用 seajs 組織的,意味著所有用 seajs 載入的 js/css, 都可以對映到任意路徑。我們以 markzhi.com
為例來說明。
正常訪問 markzhi.com 時,載入的 js 檔案都是線上的:
要將線上檔案對映到本地,首先需要在訪問地址上加上標識 http://markzhi.com/?seajs-debug. 注意右下角的懸浮層:
在輸入框裡填寫上對映配置檔案:http://localhost/seajs-map.js
seajs-map.js
的內容為:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
define(function() { var rules = []; // the map rules for markzhi.com rules.push([ 'http://markzhi.com/assets/', 'http://localhost/~lifesinger/markzhi/portal/src/main/webapp/assets/' ]); seajs.config({'map': rules}); }); |
rules 還可以是正則,比如:
1 2 3 4 5 6 7 8 9 |
// replace compressed version to debug version rules.push([ /^(.*).js$/i, '$1-debug.js' ]); |
點選 SeaJS Debug Console 懸浮層的 Refresh 按鈕,就可以看到除了 seajs 自身,其他檔案到對映到本地了:
成功對映後,可以點選 Hide 按鈕隱藏掉懸浮層,點選 Exit 按鈕是退出 debug 模式,還原到正常狀態。
注意:在 debug 狀態時,頁面的 title 會自動新增 [debug] 字首以供辨識。
除了通過 ?seajs-debug
的方式來開啟除錯控制層,還可以通過 bookmarklet 的方式來開啟:對映外掛。
這種方式的好處是:方便快捷,對除錯頁面所在機器無要求,開發機器上也只需要有 www 服務即可。比如對於 iPad 來說,可以用 ?seajs-debug
開啟配置層,讓配置檔案指向開發機器。這樣,就可以在開發機器上寫程式碼,重新整理 iPad 上的頁面立刻就可以看到修改後的效果。這種便捷,是其他幾種方式很難做到的。
壞處是:要除錯的程式碼必須是通過 seajs 載入的,這是前提條件,必不可少。除此之外,暫時想不到有什麼不妥之處。
小結
我最常用的方式是:
1.基於 seajs 的本地對映。如果要除錯的檔案是用 seajs 載入的,這種開發除錯方式非常便捷。
2.利用虛擬主機和檔案重寫。當要除錯的檔案不是用 seajs 載入的,通過這種方式,可以一次配置,永久受用。
除錯方式就如編輯器一樣,沒有最好,只有最合適。偶爾,notepad 會比 IDE 還方便,儲存到本地的除錯方式也有可能比其他任何方式都快捷。清晰地知道各種方式的利弊,合理選擇就好。
作者:歲月如歌