1.背景
移動互聯(lián)網(wǎng)發(fā)展到今天,由于H5的跨平臺往果、高效率疆液、低成本等優(yōu)勢,我們的前端開發(fā)工作內(nèi)容已不僅僅局限于瀏覽器端的網(wǎng)頁棚放,現(xiàn)在很多應(yīng)用都已經(jīng)引入了新的開發(fā)模式:Hybrid APP枚粘。
Hybrid APP底層依賴于Native提供的容器(UIWebview),上層使用HTML飘蚯、CSS和JavaScript來開發(fā)馍迄,這樣的方式使得應(yīng)用更新迭代變得更加敏捷和高效,所以Hybrid APP應(yīng)用越來越多局骤。但是隨之而來的會有很多新問題攀圈,比如今天我們要談到的實際開發(fā)中前端如何模擬客戶端環(huán)境實時調(diào)試。
傳統(tǒng)的前端開發(fā)峦甩,在PC端我們可以用瀏覽器直接打開html頁面赘来,實時查看和調(diào)試頁面,移動端可以借助類似BrowserSync這種實時同步工具來調(diào)試凯傲,但是在Native下犬辰,很多時候我們需要依賴用戶的信息或者依賴客戶端的一些行為,只能先提測或者上線冰单,讓客戶端同學(xué)給配一個測試或線上入口url幌缝,每次更新了代碼,都要push代碼诫欠,然后在客戶端內(nèi)查看效果涵卵,這還只是應(yīng)對新需求未上線的功能,一旦項目上線有bug需要修復(fù)荒叼,我們沒有客戶端的真實環(huán)境轿偎,比如測試環(huán)境沒有正式環(huán)境的某些數(shù)據(jù),很難將問題復(fù)現(xiàn)出來被廓,也不可能拿線上代碼直接去push調(diào)試坏晦,所以這種方案顯然不合理。那么有什么辦法能讓我們修改完本地代碼后嫁乘,直接重載客戶端的Webview英遭,就能實時看到Native中最新效果了呢,下面介紹一種開發(fā)模式亦渗,滿足我們的Hybrid H5開發(fā)需求挖诸。先來看看一個實際案例:
2.案例描述
前些天測試同學(xué)給我提了個bug單,大概是這樣的:我們的書城客戶端內(nèi)有一個專題法精,內(nèi)容是一些書籍列表多律,每個書籍都有一個『閱讀』按鈕痴突,bug現(xiàn)象是“打開的書籍與專題中實際點擊的不一致,打開的是該專題下最后一本書狼荞×勺埃”∠辔叮看描述猜測原因應(yīng)該是:點擊閱讀按鈕時候調(diào)用的 readbook() 方法拾积,需要傳入所選書籍信息作為參數(shù),傳參邏輯出現(xiàn)了問題丰涉。
因為這個專題模板之前不是我寫的拓巧,專題模板又兼容了多類專題,代碼量龐大一死,所以熟悉了下代碼框架后先基本確認(rèn)了問題點肛度,果然是這里的readbook() 方法的參數(shù)在列表循環(huán)數(shù)據(jù)的時候被覆蓋了,這里需要重新兼容一個邏輯處理投慈,修復(fù)完畢承耿。但是改別人的代碼最擔(dān)心的就是牽一動百,而且這個專題只有線上正式環(huán)境才有伪煤,測試環(huán)境沒有加袋,也不想再去麻煩運營同學(xué)給測試環(huán)境配一堆數(shù)據(jù),所以問題來了抱既,怎么才能在本地客戶端環(huán)境實時調(diào)試H5而不把風(fēng)險留給正式環(huán)境來測呢职烧?先梳理下思路。
3.思路梳理
我們需要搞清楚兩個問題:
1.如何本地調(diào)取線上環(huán)境接口數(shù)據(jù)蝙砌,沒數(shù)據(jù)我們無法測試該專題;
2.如何將本地代碼實時同步到客戶端內(nèi)訪問跋理。
先看第一個問題择克,我們的js網(wǎng)絡(luò)協(xié)議層的方案大概是這樣的,先判斷當(dāng)前url域名是不是線上域前普,是的話就調(diào)正式環(huán)境后端服務(wù)接口肚邢,否則就掉測試環(huán)境后端接口,網(wǎng)絡(luò)協(xié)議層一般是不動的拭卿,我不能為了測試去修改網(wǎng)絡(luò)層規(guī)則再提測骡湖,這也是不合理的,所以解決這個問題的第一步峻厚,就是模擬正式域响蕴。這里我們的方案思路是使用nginx代理服務(wù)器配合修改hosts文件來實現(xiàn),將正式域名 iyuedu.qq.com 在開發(fā)環(huán)境中直接指向本地代碼惠桃,有了這個基礎(chǔ)浦夷,第二個問題自然想到通過給手機(jī)掛代理來實現(xiàn)辖试。
4.安裝nginx服務(wù)器
首先安裝nginx服務(wù)器,以下演示以Mac為例劈狐,Windows下nginx安裝見此罐孝。
1.Homebrew安裝
Mac下nginx要通過Homebrew來安裝(簡稱brew),brew是Mac OSX上的軟件包管理工具肥缔,能在Mac中方便的安裝軟件或者卸載軟件莲兢。
Homebrew的安裝非常簡單,打開終端復(fù)制续膳、粘貼以下命令改艇,回車:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew安裝完畢后,可以在終端輸入命令「brew -v」檢查以下是否安裝成功(若失敗姑宽,多試幾次):
返回了Homebrew 1.2.1版本號遣耍,說明brew已經(jīng)安裝成功。
2.nginx安裝
接下來繼續(xù)安裝nginx炮车,執(zhí)行命令:
brew search nginx
brew install nginx
可能由于網(wǎng)絡(luò)因素舵变,安裝的時候花費了很長時間,中間失敗了兩次瘦穆,所以這里如果安裝不順暢纪隙,請多嘗試幾次即可。
同樣安裝完畢后我們可以通過命令「nginx -v」查看nginx是否安裝成功:
返回 nginx/1.12.0 版本扛或,搞定绵咱。
5.修改ngnix.conf配置
nginx已經(jīng)安裝完畢,但是我們還要通過對nginx的一些配置熙兔,讓它使我們的線上域名“ iyuedu.qq.com ”在本機(jī)中指向本地的代碼目錄悲伶。
打開Finder,前往文件夾 “/usr/local/etc/nginx/” 住涉,然后找到 nginx.conf 文件麸锉,打開并進(jìn)行編輯:
找到 http 下的 server,進(jìn)行如下配置修改:
server {
listen 80;
server_name iyuedu.qq.com;
set $path '/Users/luping/Desktop/work/git_code/baipai/oppo-webapp-html/WebContent/6_0/';
location / {
root $path;
index index.html index.htm;
autoindex on;
}
}
這里我們使用 80 端口舆声,server_name很好理解花沉,就是我們主機(jī)的名稱,我們使用線上域名“iyuedu.qq.com”媳握,然后設(shè)置一個變量$path來保存本地代碼路徑碱屁,在location中賦值給root。
保存蛾找,關(guān)閉娩脾,其他的地方保持原配置暫不用修改。
注意打毛,這里會有兩個坑晦雨,后面運行的時候再分析解決架曹。
6.修改hosts文件
hosts文件是一個用于儲存計算機(jī)網(wǎng)絡(luò)中各節(jié)點信息的計算機(jī)文件,我們可以配置ip地址和其對應(yīng)主機(jī)名闹瞧。
打開Finder绑雄,前往文件夾 “/private/etc/hosts” ,找到hosts文件奥邮,先復(fù)制一份到桌面万牺,然后打開,我們將默認(rèn)的 “127.0.0.1 localhost” 先注釋洽腺,再添加一條:
# 127.0.0.1 localhost
127.0.0.1 iyuedu.qq.com
保存后脚粟,在粘貼回 “/private/etc/hosts”目錄下,這里需要提供下管理員密碼蘸朋,繼續(xù)即可核无。至此我們的hosts文件也修改完畢,將本地的ip對應(yīng)到了我們的想要的正式域名“iyuedu.qq.com”藕坯。
7.啟動&解決問題
1.啟動
終于等到這一刻团南,是時候看一下修煉成果了,我們需要啟動nginx服務(wù)炼彪,這里先普及下nginx常用的幾個命令:
sudo nginx #打開 nginx
nginx -s reload|reopen|stop|quit #重新加載配置|重啟|停止|退出 nginx
nginx -t #測試配置是否有語法錯誤
nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]
-?,-h : 打開幫助信息
-v : 顯示版本信息并退出
-V : 顯示版本和配置選項信息吐根,然后退出
-t : 檢測配置文件是否有語法錯誤,然后退出
-q : 在檢測配置文件期間屏蔽非錯誤信息
-s signal : 給一個 nginx 主進(jìn)程發(fā)送信號:stop(停止), quit(退出), reopen(重啟), reload(重新加載配置文件)
-p prefix : 設(shè)置前綴路徑(默認(rèn)是:/usr/local/Cellar/nginx/1.2.6/)
-c filename : 設(shè)置配置文件(默認(rèn)是:/usr/local/etc/nginx/nginx.conf)
-g directives : 設(shè)置配置文件外的全局指令
好了辐马,首先我們啟動nginx:
sudo nginx
按照配置拷橘,我們把本地的localhost修改為了“iyuedu.qq.com”,然后直接指向了代碼目錄喜爷,所以理論上我們打開瀏覽器直接訪問 “http://iyuedu.qq.com/topicV2.html” 就可以訪問到這個專題文件topicV2.html了冗疮,試一試:
發(fā)現(xiàn)nginx給我們報了個錯,提示 “403 Forbidden”檩帐,目測是權(quán)限問題术幔,nginx不允許查看〗嗡看來我們還要再修改一下nginx.conf配置文件特愿,在nginx.conf文件的最頂部加一句
user root owner;
保存仲墨,然后在終端重啟nginx:
sudo nginx -s reload
在瀏覽器中再刷新一下:
看樣子好像成了勾缭,我們幾乎達(dá)到了目的,本地訪問域名“iyuedu.qq.com”但實際訪問的是本地的代碼目养,而且顯然已經(jīng)成功的取到了后端線上接口數(shù)據(jù)俩由,經(jīng)測試,修改了一下本地代碼癌蚁,瀏覽器中一刷新幻梯,頁面會立刻看到更新改動兜畸,這不正是我們想要的嗎,但是碘梢,好像還差那么一點點咬摇,對比了下這個專題真正的線上url,是這樣的:
http://iyuedu.qq.com/act/6_0/topicV2.html
而我們目前模擬出來的是:
http://iyuedu.qq.com/topicV2.html
對比發(fā)現(xiàn)煞躬,我們模擬的url缺少了一部分路徑 “/act/6_0”肛鹏,這樣的話顯然不能進(jìn)行下面的代理客戶端中頁面url的工作了,所以我們必須要模擬得一模一樣恩沛!
好吧在扰,我們繼續(xù)填坑。
2.解決雷客,location中root和alias
上面我們只是用nginx和hosts來啟動了服務(wù)和修改了本地ip對應(yīng)的主機(jī)名稱為我們的正式域名芒珠,那么繼續(xù)給這個域名配一個虛擬的路徑,誰來做呢搅裙?當(dāng)然還是nginx皱卓, hosts文件能力有限,只能修改一下主機(jī)名稱呈宇,真正挑大梁的還是nginx好爬。
原來nginx.conf中的location指定文件路徑有兩種方式:root和alias。
root與alias主要區(qū)別在于nginx如何解釋location后面的uri甥啄,這會使兩者分別以不同的方式將請求映射到服務(wù)器文件上存炮。
[root]
語法:root path
默認(rèn)值:root html
配置段:http、server蜈漓、location穆桂、if
[alias]
語法:alias path
配置段:location
root實例:
location ^~ /path/ {
root /www/page/html/;
}
如果一個請求的URI是 /path/a.html 時,web服務(wù)器將會返回服務(wù)器上的 /www/page/html/path/a.html 的文件融虽。
alias實例:
location ^~ /path/ {
alias /www/page/html/;
}
如果一個請求的URI是 /path/a.html 時享完,web服務(wù)器將會返回服務(wù)器上的/www/page/html/a.html的文件。注意這里是 /www/page/html 有额,因為alias會把location后面配置的路徑“/path”丟棄掉般又,把當(dāng)前匹配到的目錄指向到指定的目錄。
知道了這一點巍佑,我們要做的就是使用alias修改一下nginx.conf茴迁,我們?nèi)鄙俚穆窂绞恰?strong>/act/6_0/”,所以修改如下:
server {
listen 80;
server_name iyuedu.qq.com;
set $path '/Users/luping/Desktop/work/git_code/baipai/oppo-webapp-html/WebContent/6_0/';
location ^~ /oppo/6_0/ { // *修改下location*
alias $path; // *使用 alias *
index index.html index.htm;
autoindex on;
}
}
保存nginx.conf文件萤衰,然后再次重啟nginx服務(wù):
sudo nginx -s reload
再次回到瀏覽器堕义,我們輸入線上正式的url:
http://iyuedu.qq.com/act/6_0/topicV2.html?tid=327950&tf=1
刷新,頁面正常顯示:
但是脆栋,這個頁面訪問的代碼到底是不是我們本地的代碼呢倦卖,試一下便知洒擦,我們修改下“閱讀”按鈕的文案為“test”,保存看看是否及時生效:
沒毛病怕膛,成了熟嫩,現(xiàn)在我們已經(jīng)完全在本地模擬了線上正式域頁面的url
,也成功取到了線上接口數(shù)據(jù)褐捻,接下來就是在客戶端內(nèi)實時預(yù)覽這個頁面了邦危。
8.客戶端實時預(yù)覽H5
我們已經(jīng)在本地啟了nginx服務(wù),修改了主機(jī)名為線上域名舍扰,所以接下來我們只需要讓手機(jī)和Mac處于同一個局域網(wǎng)內(nèi)倦蚪,并且給手機(jī)掛上代理,就可以在線上包客戶端內(nèi)訪問到我們的本地代碼頁面了边苹,有了客戶端環(huán)境陵且,我們就可以更方便地進(jìn)行調(diào)試了,這正是我們想要的个束。
給手機(jī)掛代理慕购,我們需要在電腦上啟動一個常用的抓包軟件,Mac上我用的是 Charles茬底,Windows下一般是Fiddler沪悲,啟動后一般默認(rèn)端口是8888,當(dāng)然也可以自己修改阱表,這里我們就不修改直接使用默認(rèn)的端口號8888殿如。
然后再找一下電腦當(dāng)前的ip,Mac-設(shè)置-網(wǎng)絡(luò) 就可以看到我的是192.168.1.112最爬。
注意涉馁,有的公司的內(nèi)部局域網(wǎng)考慮安全因素設(shè)置了比如AP隔離等,導(dǎo)致連接到同一局域網(wǎng)內(nèi)的設(shè)備不能互相通信爱致,當(dāng)然也不能進(jìn)行抓包等操作烤送,這種情況下需要我們使用電腦開啟網(wǎng)絡(luò)熱點來讓移動設(shè)備連接,關(guān)于Windows和Mac開啟熱點的方式:
Windows用戶看這里
Mac用戶看這里
拿出我們的手機(jī)糠悯,連接到與當(dāng)前電腦同一個wifi局域網(wǎng)帮坚,對該wifi網(wǎng)絡(luò)進(jìn)行高級設(shè)置-代理,主機(jī)名輸入我們的電腦IP互艾,端口輸入8888试和,然后確定保存,這時我們的手機(jī)就已經(jīng)掛上代理了忘朝。
然后打開app客戶端灰署,找到這個專題判帮,點擊進(jìn)去局嘁,發(fā)現(xiàn)這個頁面的“閱讀”按鈕的文案已經(jīng)是“test”了溉箕,說明我們的客戶端由于手機(jī)掛上了我們的本地網(wǎng)絡(luò)代理,url自動指向了本地代碼目錄悦昵。這樣肴茄,我們的終極目標(biāo)就達(dá)到了,現(xiàn)在客戶端環(huán)境下但指,我們已經(jīng)可以隨時調(diào)試本地的H5代碼了寡痰。
9.小結(jié)
這只是一個開發(fā)模式上的優(yōu)化方案,雖然略復(fù)雜麻煩一些棋凳,但是也大大提高了開發(fā)的效率和可靠性拦坠,也切實為我們解決了一些棘手的問題。由于本人經(jīng)驗和能力有限剩岳,文中提到的一些地方如有描述不準(zhǔn)確或者錯誤的地方贞滨,歡迎大家指正,也相信還有更加便捷的方法來實現(xiàn)這個需求拍棕,先這樣吧晓铆,88。 [愉快]