甄玉磊京東UED前端攻城獅,熱愛嘗試各種新穎技術
“起初我只是想做一個網頁,卻一不小心掉入代碼的海洋里!”
平臺是在 開源框架基礎上,進行了深度二次開發(fā)和功能擴展。不僅打通了/iOS/Web三端平臺,而且對京東移動端基礎業(yè)務能力進行了SDK級別的封裝,提供了統(tǒng)一、易于開發(fā)的API。基于以上種種優(yōu)勢,加油卡殼牌業(yè)務決定使用技術進行開發(fā)。
1前期準備
1.1 項目背景
加油卡殼牌業(yè)務是京東APP中的一個項目,可以從首頁的「充值繳費」入口進去,如下視頻演示:
1.2 項目環(huán)境配置
初始項目中只包含一個dev分支,最后打包APP時會從該分支中抽取代碼,所以我們新建了一個trunk分支,平時在該分支上進行開發(fā),最后打包APP的時候再切換到dev分支,合并代碼。
對于文件結構,如上圖所示,其中.js設置頁面路由信息,以及打開項目時進入的默認頁面;pages文件夾下存放項目的每個頁面代碼;
存放項目開發(fā)中使用到的圖片;文件夾下存放頁面中用到的各個組件。
按照團隊給出的安裝依賴環(huán)境的步驟,當執(zhí)行npm start命令之后,理想狀態(tài)下會出現下面的提示:
很不幸的是,有時候會出現如下警告:
根據提示,可以看到打開.babel.json文件的時候出錯,其實如果忽略這些警告,也可以打開京東APP進行調試的,但是如果想解決這個問題可以參考下面的步驟:
找到C:\Users\用戶名\.babel.json文件右擊——屬性——安全——的權限全部改為允許(如果已經改過權限,可以來回切換一下)頁面數據加載出錯是怎么回事,重新執(zhí)行npm start就可以了。
項目是在中開發(fā)的,但是在編寫代碼時,整個代碼的高亮是混亂的,如下圖所示:
因此,需要安裝Babel 插件來解決高亮問題,該插件可以使React.js、JSX語法代碼高亮。安裝方式:在中,ctrl+shift+p打開面板選擇 ,輸入babel 點擊安裝,安裝完畢后再次ctrl+shift+p,選擇set (babel),則React語法代碼可以高亮,方便我們接下來的開發(fā)。執(zhí)行完畢后效果如下圖所示:
1.3 在無線持續(xù)構建平臺打包項目
手機安裝debug版本的京東APP之后,可以在手機端實時看到開發(fā)的代碼效果,那么如何生成APP呢?因為構建平臺會抽取項目中dev分支的代碼,所以如果代碼有所改動,先把trunk分支代碼合并到dev分支。整體思路是把業(yè)務代碼以插件形式打包進,然后再打包包含該插件的APP。打包流程如下:
對于版本,首先打開無線構建平臺網址,選擇一鍵打包——,依次選擇插件名稱——平臺選擇()——dev 分支——點擊開始構建。
打包好后,再打包京東APP:
選擇京東商城————其中debug版本可以晃動手機進行調試,版本不可以調試,近似于真實環(huán)境,所以如果平時開發(fā)調試的話選擇debug版本——選擇dev分支——開始構建。
一般來說版本的打包過程還算順利,但是IOS版本的打包過程就讓人心碎了,下面我們來聊聊IOS版本:
首先仍舊是插件的打包,類似版本的打包過程,對于IOS不同的是版本選擇IOS,分支選擇dev點擊開始構建。
IOS的插件構建完成之后,類似的在京東商城選擇IOS——這里的IOS 版本是用來調試的版本,遺憾的是我們多次下載版本在手機端總是打開之后閃退,還好版本也可以進行調試,雖然不是很方便,但也可以解燃眉之急:
1.4 手機安裝APP
按照上述過程生成APP,版本的APP和IOS版本的APP接下來的步驟有所不同,對于版本,直接掃描構建平臺——歷史版本生成的二維碼,安裝京東APP,注意下面的步驟:
打開調試模式;
如果使用的是真實環(huán)境,還需要在服務器設置中取消選擇“前兩項”,測試環(huán)境需勾選“前兩項”;
每次安裝完新的APP之后,一定要記得晃動手機,dev ——設置 Debug host & port for 這個選項端口8081,如果報錯could not to ,需要檢查一下防火墻是否打開了8081這個端口:控制面板——防火墻——高級設置——入站規(guī)則——新建規(guī)則——端口——特定本地端口:8081——選擇允許聯機連接——一直點擊下一步。
對于IOS的版本:需要在構建平臺——歷史版本中找到打包好的ipa 后綴文件,使用軟件安裝到手機,該過程需要注意的是:
電腦端開啟npm start服務(同樣保證防火墻對端口8081的不限制);
手機連接電腦的wifi,手機瀏覽器登錄跳轉協議頁面
在列表輸入框的鏈接改為自己電腦的ip地址和端口,文件名字改為自己的項目名,點擊React按鈕打開。
如果是真實環(huán)境,打開手機APP時,選擇的環(huán)境,否則選擇測試環(huán)境;
每次改動代碼之后頁面數據加載出錯是怎么回事,需要退出后臺的京東APP,然后先打開APP,選擇host 環(huán)境,最后在跳轉協議列表頁面重新用“React打開”按鈕打開項目。
2項目開發(fā)中的問題
在項目開發(fā)過程中遇到了很多問題,這里總結了幾個具有代表性的問題:
2.1 加載圖片問題
使用組件加載本地圖片和線上圖片的方式是不一樣的,如果不加注意很容易把兩者混淆:
線上的圖片直接使用uri:
加載本地的圖片使用的是:
并且每次新增本地圖片,控制臺都會報錯:... '◆'(1:0) at ...
這是因為新增加的圖片必須重新npm start。
2.2 通過路由完成頁面之間的跳轉
由于文檔不全,路由之間如何傳遞參數,如何獲取參數沒有說明,導致在這里也花費了不少力氣。對于頁面之間的跳轉,我們剛開始使用 中的 方式進入某個路由:
1
2
3
4
this...reset([
{:'index',:{title:'apis'}},
{:'',:{datas:this.props.}}
],1);
則下一個頁面獲取路由參數的方式是:this...()[1]..title;
隨著項目開發(fā),發(fā)現這樣有個問題,例如從A頁面跳轉到B頁面,如果從B頁面回退到A頁面,A頁面之前的操作狀態(tài)會全部清空,因此,為了保留A頁面的狀態(tài),改為使用push方式進入某個路由,用返回上一個路由,這樣的方法可以保留原頁面的狀態(tài),但是如何獲取路由攜帶的參數,文檔中則沒有介紹,經過多次嘗試,我們發(fā)現需要這樣設置:
A頁面通過push跳轉到B頁面并傳參:
1
2
this...push({:'B',props:
{datas:this.props.}});
B頁面獲取參數方式:this.props.datas.data,B頁面返回上一頁面使用 ,并傳參:this...('A',{:null});。A頁面獲取參數方式:this...()[0]..
2.3 修改底層組件
誠然底層封裝的組件可以滿足項目開發(fā)中的大部分需求,但是有些特殊需求,暫時不能滿足,比如加油卡項目中設置密碼的彈窗,設置按鈕的字體在不同狀態(tài)下要有對應的顏色
該密碼彈窗組件是在組件的基礎上開發(fā)的,但是該組件并沒有提供確定按鈕位置樣式的變化,于是我們找到底層封裝組件的目錄/@///index.js文件,為了不影響底層組件,我們復制出該文件,在
1
2
3
{this.props.}
的位置增加可以傳入設置文本的樣式:
1
2
3
{this.props.}
這樣就可以在組件外面設置按鈕的樣式了。
2.4 使用方法
對于版本的APP:在debug的客戶端中選擇設置——debug配置——服務器設置——如果勾選前兩項就是測試環(huán)境api.m.jd.care(經過咨詢得知和api.m.jd.care都對應著測試環(huán)境,區(qū)別只在于支持https,而api.m.jd.care這個網關是不支持 https),如果去掉勾選前兩項,host就是;
對于IOS的版本則需要在點擊“ React 打開”按鈕啟動APP時選擇需要的host環(huán)境。
2.5 換行問題
組件開發(fā)的樣式布局和常用的H5開發(fā)樣式布局,多少還是有所不同。例如,項目中用戶勾選協議部分如下圖所示:
因為黑色字體使用 組件包裹,紅色字體點擊需要出現彈窗,所以紅色字體部分需要使用點擊組件 標簽包裹,查看 底層代碼可以看到里面是用 標簽搭建的組件,所以 生成的黑色字體(行內元素)和 包裹的紅色字體(塊級元素)無法像上圖一樣,只能分成多行顯示:
這顯然無法滿足樣式的需求,解決方法是紅色的字體部分也使用 ,點擊事件放在 上面,并且用上一級的 嵌套,代碼如下所示:
1
2
3
4
5
請您確認京東將收集您上述信息實現本服務,本服務約定請詳見
《殼牌加油卡充值協議》
這樣就達到了我們想要的樣式。
2.6 組件之間的層級問題
按照最初的構思,每個功能塊作為一個組件進行封裝,如上圖所示,“電話輸入框”組件和“選擇面值”組件是兄弟關系,其中“電話輸入框”包含了歷史號碼列表(如右圖所示),這里把電話輸入框設置為相對定位,歷史列表設置為絕對定位,在系統(tǒng)下歷史列表可以正常顯示,但是在IOS系統(tǒng)下,原本在“選擇面值”組件層級之上的歷史列表卻被“選擇面值”組件覆蓋掉了,為了兼容兩個系統(tǒng),把“選擇面值”組件合并到“電話輸入框”組件之中,這樣,在同一個組件中,確保了歷史列表的層級就在“選擇面值”之上,從而可以在兩個系統(tǒng)中正常顯示了。
2.7 的使用
在項目中,每個組件都需要獲取用戶登錄信息,如果每個組件都調用獲取用戶的登錄信息,顯然是冗余的,那么有什么方法可以優(yōu)化嗎?我們可以在父組件中獲取一次用戶登錄信息,然后分發(fā)到每個組件中,這樣無疑減少了很多重復,但是從父組件傳遞到后代組件,數據層層下傳也會造成很多的麻煩。如果有方法可以把數據從父組件直接下傳到后代組件就好了,這時就派上用場了。例如需要把頂層組件的color數據傳遞到底層組件中,結構示意圖如下:
猶如在頂層組件和后代組件之間打開了一條直通大道,可以從父組件中把數據直接傳遞到后代組件而不需通過中間組件傳遞,其使用方法簡化如下:
(1)首先在頂層組件中定義color的類型:
1
2
3
.={
color:React..
};
定義頂層組件所擁有的子類對象——該頂層組件所擁有的子類對象為color,且必須為字符串類型。
然后通過方法,來給子對象的屬性賦值:
1
2
3
(){
{color:"red"};
}
這樣就完成了頂層組件中,對象的賦值。
(2)越級傳遞,因為color屬性只在最底層使用,在一級子組件(圖中的中間子組件)中并沒有直接用到,因此我們可以直接傳遞到最底層(越級),在組件中使用。
首先組件中,再次聲明了所接受到的的子組件color類型,聲明必須為字符串:
1
2
3
.={
color:React..
};
然后可以通過this..color這種方式調用:
子組件
綜上所述,我們通過就能實現值的越級傳遞。從而簡化了邏輯和代碼復雜度。
3調試
關于手機APP調試代碼的具體步驟,詳見 1.4。使用debug版本的APP,晃動手機可以出現調試的選項,這里我們解釋一下常用的幾個功能:
4上線
上線流程其實按照團隊給出的發(fā)布規(guī)范走就可以了,作為前端的工作也就是要壓縮圖片,保證生成的升級包不要大于1M。升級包由團隊上線,后端研發(fā)部署H5頁面,上線完畢后,測試人員在無線持續(xù)集成平臺的歷史版本中下載安裝相對應測試版本的 和IOS版本進行測試。在這個過程中要注意的是:
安裝好客戶端之后,需要把系統(tǒng)時間往后調整30分鐘才能看到效果,一般上線往往延遲到凌晨左右,如果跨夜上線的話,不但要往后修改30分鐘,一定要注意還要往后修改一天日期。例如系統(tǒng)時間為11月4日23:40,需要將時間改為11月5日00:10。
集成平臺上的安卓版本目前分為dev分支、分支、發(fā)版分支。其中dev分支和分支都是從git庫中的dev分支上抽取代碼的,而每次客戶端升級的發(fā)版分支是從分支上抽取代碼的,所以上線測試完成之后,還需要在集成平臺上打包分支,保證該分支是最新的代碼,這樣下次客戶端升級才會包含本次上線的業(yè)務代碼。
值得注意的是每次客戶端升級之后對應的git庫都要新拉出一個對應版本號的分支,如果有問題,可以在該分支下修改代碼,然后在集成平臺上對應的發(fā)版分支上抽取代碼,因為此時你再修改git庫中的dev分支無法影響發(fā)版分支;換句話說,分為兩種情況:
綜上所述,你需要做的如下所示:
對于之前已經上線的客戶端,你需要生成升級包,由團隊上線;
然后更新集成平臺上的分支,保證之后版本的客戶端包含你的業(yè)務;
每次客戶端更新之后,你需要在git庫中新拉一個對應版本的分支,修改完畢后,將其打包到正在灰度的發(fā)版分支上;
最后再次更新git庫中dev分支,更新集成平臺中的分支;
IOS系統(tǒng)和系統(tǒng)類似,IOS系統(tǒng)目前打包到dev分支(之后可能會有改動),這樣才能保證以后每次的新版本發(fā)布,帶上此次開發(fā)的項目。