基於React Native的移動平臺研發實踐分享
本文目錄:
一、React Native 已經成為了移動前端技術的趨勢
二、基於React Native 進行移動平臺研發過程中的一些思考
三、基於React Native 進行移動平臺研發過程中的一些實踐
四、小結
一、React Native 已經成為了
移動前端技術的趨勢
從2014年年底,Facebook計劃開源React Native 的時候,我就已經開始關注TA了,關注的主要原因是,我們在2012年的時候,將我們的移動平臺前端開發技術確定為“DSL->Javascript->Native Mobile”這個技術流派。要知道在那個時代,絕大多數的友商要麼選擇Hybrid,要麼選擇HTML5作為移動平臺的跨平臺前端解決方案。
然而,這兩種方案最終的UI渲染,本質上都需要依賴Webkit,通俗點說就是UI最終是通過瀏覽器核心渲染。我們當時在技術選型的時候實在無法容忍Webkit在Andriod上的體驗,而選擇了驅動原生(注:這個名字是我起的,也是為了區別於傳統的Hybrid技術)的方式。
當時的這個技術抉擇,在當時是冒著巨大的風險的,現在看來,我們是非常幸運的。
後來Facebook 推出React Native 後,阿里系也推出了自己的Weex,甚至Gartner針對這類技術在2016年的報告(IT Market Clock for Mobile App Development, 2016 )中首次出現並併為這個技術流派起了一個名字——Javascript Frameworks for Native Mobile。
Garnter將這個技術流派當如了“Advantag”中,可見Gartner對這個技術流派的認可。
Javascript Frameworks for Native Mobile這類技術的幾個特點:
-
開發期基本採用類Web語言,比如React的語法。
-
執行期並不是採用Webkit做渲染,而是採用Native的渲染方式。
-
與Native 進行互動的通道是採用Javascript的方式。
當然,因其技術的先進性讓各大網際網路公司紛紛進行實踐上的嘗試,取得了不錯的效果,包括天貓、騰訊QQ、手機百度、美團點評、攜程等等。React Native 也建立了很好的生態,大家對案例如果有興趣可以關注一下
二、基於React Native 進行移動平臺
研發過程中的一些思考
儘管React Native 在移動前端存在著無可比擬的優勢,但每一家在工程化的過程中還是存在各自不同的思考。而作為移動平臺,不是簡單的解決單一的一個App的問題。
移動平臺是支撐企業全面移動資訊化的平臺,需要解決企業面向不同場景下的各種訴求。針對移動App的使用者的場景不同,存在面向人和麵向組織兩種不盡相對的要求:
面向人:每個人對應的App功能是基本相同的。人與人是平等的,就如今天線上的各位和我一樣,在支付寶裡看到的功能是相同的。這種情況多出現在面向最終消費者的時候。
面向組織:是指功能因其所屬的組織和職級決定了其所見和所能用的功能。當事人所處的組織機構發生了變化,功能也隨之產生變化。
針對面向組織,需要舉個例子來說明一下:假如我本人之前是一名普通的manager,其實對於產品線的經營報告並無權閱讀(圖一);當我被Promote 為產品線總經理的時候,我的App裡就應該有“智慧報表”的微應用(圖二);當我調崗到別的團隊(比如從事行政工作),我就不應該再具有“智慧報表”的相關功能(圖三),如下圖所示:
隨著崗位和職級的變化,功能從圖一到圖二再到圖三,我還是我,而我App內的功能卻發生了變化,這在企業中是非常常見的訴求。
實現上述的功能,從技術方案角度看,有多種方式,但是怎麼更合理呢?我們可以思考一下。
首先,“智慧報表”功能是否可以將UI已經打入App中,通過許可權控制對應的前端“智慧報表”是否顯示?回答是不可以。主要原因有三:
-
類似這種功能在企業中非常多,如果要將UI全都打入到App中,這需要所有功能的全集,沒有三四百M下不來。而使用者實際上只有許可權使用幾分之一甚至是十分之一的功能,卻要每次為此多更新兩三百M,這是不合理的。
-
如果智慧報表這個功能在使用者安裝ipa或者apk的時候,尚未開發完成,而是後續才迭代上線的,那麼這個使用者就無法及時使用到這個功能。
-
如果失去了相關的功能許可權,需要的是相關的功能清除,甚至包括其相關的資料,而不是簡單的隱藏,這既不安全又不合理。
這就意味著,移動平臺必須能夠動態的方式更新應用內功能,而且必須能夠結合許可權提供按需的熱更新能力。
其次,在企業中不得不面對的是多供應商的問題,智慧報表功能跟其他功能(比如:審批)是一個開發團隊開發的嗎?
顯然,在企業中完全有可能是不同的供應商進行的開發。不同供應商之間,不
可能做到程式碼級的共享的,拿到所有移動專案的程式碼再進行打包,這是一件非常難以推動的事情。
移動平臺必須保證對於多團隊、跨地域的方式也能支援並行研發。這就意味著必須提供開發期的隔離。
移動平臺需要支撐上述的業務場景,顯然直接使用React Native 是難以滿足要求的,這就引發了我們對於React Native實踐的一些思考。
思考一:React Native 的學習成本和可替換性
作為移動平臺,不得不考慮的是學習成本,在企業的供應商中是否能夠對React Native的技術儲備達到相關的要求,如何能夠遮蔽對於技術實現的細節。
眾所周知,React Native 釋出版本非常的頻繁,一個周之前已經發到0.44,對於大規模使用時,如何遮蔽版本的頻繁升級導致的業務程式碼的重構,方便進行版本的可替換性。
如果能夠將React Native實現換成其他實現(比如Weex),而上層業務程式碼能否不需要調整,真正做到實現的可替換性。
基於這一點的思考,移動平臺採用了基於傳統Web語法的DSL,作為開發期語言,降低了RN的學習成本;同時DSL層可以隔離業務程式碼與平臺實現相關性,為後續RN版本更新等提供了良好的隔離,大致的示意圖如下:
這裡需要說明的一點是,我們並沒有真正考慮基於Weex作為移動平臺的一種實現,而是從技術架構上成為一種可能性。
思考二:React Native 的單bundle VS 多bundle
在談論React Native的單Bundle與多Bundle的問題之前,首先,我們先回頭看一下React Native 預設的Bundle 機制。
在基於RN編寫App時,無論開發期建立多少個檔案,RN都會將這些檔案一併打到一個bundle裡去,簡單說預設的RN就是一種單bundle的方式,其打包bundle的大概過程如下:
因React Native 預設採用的是單Bundle的模式,所以,其更新機制也就僅僅能夠以替換這個Bundle的方式進行,雖然有一些通過diff的方式提供增量更新的方式,但這種方案仍然無法滿足上面例子中的“智慧報表”的按需獲取的能力。
另外,在進行編譯打包的時候,需要獲取所有專案的原始碼,這對於多供應商的情況下也不適用。
所以需要解決的兩個問題是:
1、在打包Bundle時,必須提供以多Bundle的方式進行。
2、在開發期,必須解決多微應用每個能夠獨立以Project的方式存在。
思考三:React Native 的除錯的首屏進入VS 當前屏重新整理
對於開發工程師,很重要的工作就是除錯,以RN預設的單Bundle模式,勢必會帶來另外一個挑戰,就是當資源發生任何變化時,必須重複上述的打包Bundle的過程並進行載入,看到的UI介面永遠是第一屏。
實際上,我們期望的絕大多數場景是看到當前修改的資源所在的屏的UI效果。從這個維度看,我們必須能夠將Bundle控制在一個資源的粒度,並確保當前bundle的動態熱更。
另外,雖然React Native 預設不承諾跨平臺,但跨平臺(即一套程式碼同時支援iOS、Andriod)是移動平臺的必備特性了。如何能夠支援多屏同時除錯,也將是一個必須考慮的問題。
思考四:React Native 的熱更新VS 按需更新
說到熱更新,這裡不得不提的是幾個月前,一堆的App被蘋果拒掉的事情,這個事情曾一度讓React Native 等Javascript Frameworks for Native Mobile 技術流派背黑鍋。
其實這件本質上還是因為某些熱更方案呼叫了私有的API而引起的,後來導致的局面時一堆三方的SDK都受到牽連,最終導致了使用這些SDK的App被拒。插一句,我個人覺著第三方的SDK在沒有讓使用它們的App知曉的情況下就進行熱更新,就是耍流氓,誰又能保證更新後的SDK不做點什麼呢。
回到熱更本身,我認為,基於React Native 進行熱更應該是一個必須的特性,而實際上我們需要提高要求,提供按需更新的能力。
三、基於React Native 進行移動平臺
研發過程中的一些實踐
基於上面的一些思考,我們基於React Native進行了一些實踐,這裡挑出幾點給各位做個簡單分享。
實踐一:引入DSL層
首先,我們引入了DSL層,這裡的語法採用了傳統Web工程師熟知的HTML、CSS、Javascript,而使用移動平臺的工程師無須對React進行過多的深入。在HTML的標籤定義中,從語義上儘量能夠對開發人員親切,從習慣上儘量保留原有開發人員的一些習慣,比如對state的封裝以getter、setter的方式提供能力,而這些標籤需要一一以React Component的方式進行了實現。我們以Label為例(後續出現的程式碼均為示例程式碼片段):
DSL語言會在開發期編譯成JSX,然後再編譯成可被React Native 執行的javascript(涉及到拆分Bundle和編譯,這裡暫不展開)。
DSL編譯成JSX,主要的工作原理大致如下:
-
HTML 標籤的處理,主要是與RN的render進行關聯
-
CSS 的處理,主要是與RN的StyleSheet進行對映
-
Javascript的處理,主要是嵌入到JSX中
上面的程式碼示例左側為基於DSL語言編寫的程式碼,右側是生成JSX後的程式碼。
實際上,在工程化過程中,並不是像上面的示例程式碼那麼容易做好,無論標籤的定義,還是從DSL轉換成JSX都是一個巨大的工程,且會遇到很多的問題。
實踐二:拆分Bundle
在拆分Bundle上,我們遵守兩個原則:
1、將系統庫作為一個bundle檔案,獨立存在。
2、將每個的Module作為一個獨立bundle檔案
這種拆分原則將bundle拆分成小粒度的針對Module級別的bundle,這帶來的好處是,可以方便的跟DSL中HTML檔案進行一一對映,其載入單元的粒度可以理解為Page級別,而非整個App。
我們以require 為例,下圖為預設的載入方式,如果沒有對應的Module Factory,就會以異常結束,如下圖:
擴充套件後,當判斷沒有對應的Module Factory的情況下,並不是以異常退出,而是增加了載入對應的Module級別的bundle,如下圖所示;
當然,這就必須需要移動平臺自行實現RTC_PM_JSCExcutor用於載入Module級別的Bundle。這一部分程式碼需要採用原生的Object-C或者Andriod Java實現,下面以iOS的示例程式碼
實踐三:引入微應用
在將每個Module打成一個Bundle後,會讓專案內資源的關係不易管理,這時我們引入了微應用的概念,用於完善應用內邏輯關係。
1、將原有的一個App對應一個Bundle的模式,改成一個App對應多個MicroApp,一個MicroApp對應多個Bundle模式。
2、將原有的一個Bundle對應多個Module的模式,裁剪成一個Bundle對應一個Module的模式
實踐四:多屏除錯
多屏除錯與當前屏重新整理,在移動平臺IDE端的產品的定義中還是佔有很重要的地位,因其直接影響了開發期的效率。
針對React Native 預設的編譯核心框架,我們簡單的可以總結為四件事情:
-
node-haste:主要是監聽Module變化 ,把變化的Module從Module快取中移除。
-
ModuleCache:Module編譯快取,把編譯好的Module快取起來,Module沒有發生變化的情況下,直接使用快取組裝成bundle
-
Resolver:實現全域性系統級庫,語法級相容實現,包括:ES5,ES6實現 相容實現的引入 。實現Module factory的包裝
-
JSTransformer:呼叫Babel編譯JSX檔案到JS。
其中1和2有很大原因是因為單bundle導致,當每個HTML檔案對應一個Module,每個Module 對應一個bundle後,移動平臺需要的就是監聽HTML等檔案的資源變化即可。如下圖:
而這裡的編譯引擎基本上做的事情是:
1、DSL->JSX
2、JSX->js
其中後者主要的工作如下所示:
而為了能夠更好的除錯,需要對相關兩種更新機制:
-
批量更新
a)包括初次批量更新部署,下載所有檔案
b)使用過程中檢查檔案更新部署,判斷需要更新的檔案列表
-
單頁更新
單頁更新是確保其可以當前頁儲存,當前頁重新整理除錯的主要機制
通過上述的方式,結合移動平臺的IDE,可以提供
1、同時支援多手機終端的多屏除錯(可以同時iOS和Andriod)
2、提供了當前屏動態重新整理動態除錯
實踐五:按需熱更
當上述的實踐完成後,按需更新就成了一個相對較容易做到的事情。所以移動平臺提供了兩級打包編譯機制,在無需調整程式碼的情況下,可以選擇以微應用的方式出現其他的App內,還是以獨立的ipa/apk的方式存在以移動裝置中。其基本原理如下圖所示:
四、小結
基於React Native進行移動平臺研發是一個系統性的工程,上述的工作僅僅是其中的一小部分,期間的坑還有很多,這篇文章也僅是從大粒度的方面進行了分享。
希望本次分享對大家能有幫助,也希望各位專家能夠多多拍磚。
拍磚方式如下:
相關推薦
基於React Native的移動平臺研發實踐分享
本文目錄: 一、React Native 已經成為了移動前端技術的趨勢 二、基於React Native 進行移動平臺研發過程中的一些思考 三、基於React Native 進行移動平臺研
基於React Native的跨三端應用架構實踐
作者|陳子涵 編輯|覃雲 “一次編寫, 到處執行”(Write once, run anywhere ) 是很多前端團隊孜孜以求的目標。實現這個目標,不但能以最快的速度,將應用推廣到各個渠道,而且還能節省大量人力物力。 React Native 的推出,為跨平臺的開發帶來了新的曙光。 雖然 Facebo
【視訊】基於React Native的跨三端技術實踐
前言今天由京東 @ 劉威在今年 FEDAY 分享的《基於React Native的跨三端技術實踐
雲上拍客梨視頻 基於阿裏雲的技術實踐分享
CI scim .com 覆蓋 nbsp acf AC 個性 雲架構 摘要: 梨視頻大部分的業務都選擇了阿裏雲,其中一個主要原因是阿裏雲提供基於釘釘群構建的24貼身技術支持,劉雋表示,這種服務模式可以更充分、高效的對接需求,快速得到反饋,這也讓梨視頻的同學有信心去嘗試一些新
基於React Native封裝的資訊頻道TopBar,常見於新聞客戶端react-native-scrollable-topbar
react-native-scrollable-topbar 基於React Native封裝的資訊頻道TopBar,常見於新聞客戶端,具體實現功能如下: TopBar區域可手動滑動(Underline 聯動) 點選頻道實現內容區切換 根據內容區(this.p
基於React Native官方元件FlatList,增加可定製化“下拉重新整理”、“下拉載入更多”元件API的新列表元件react-native-refresh-loadmore-flatlist
react-native-refresh-loadmore-flatlist 基於React Native官方元件FlatList,增加可定製化“下拉重新整理”、“下拉載入更多”元件API的新列表元件,具體實現功能如下: 自定義下拉重新整理元件API 自定義上拉Lo
基於React Native實現的介面載入元件react-native-loadview
react-native-loadview 基於React Native實現的介面載入元件, Installation npm install react-native-loadview --save Import into your project import
基於React Native封裝的表單提交Container,用於替代RN官方元件KeyboardAvoidingView(不相容Android)react-native-keyboardavoidv
react-native-keyboardavoidview 基於React Native封裝的表單提交Container,用於替代RN官方元件KeyboardAvoidingView(不相容Android) Theory 重寫TextInput的onFocus方法,藉助Sc
基於React Native官方元件Image封裝的具備載入生命週期視覺反饋的元件react-native-loading-image
react-native-loading-image 基於React Native官方元件Image封裝的具備載入生命週期視覺反饋的元件,具體實現功能如下: 網路圖片Pending狀態渲染,提供閃爍動畫、loading.gif兩種方式 網路圖片Error狀態渲染
基於React Native官方元件ScrollView與React-Navigation實現headerTitle與介面的滑動的互動效果react-native-scrollable-contain
react-native-scrollable-container 基於React Native官方元件ScrollView與React-Navigation實現headerTitle與介面的滑動的互動效果 Installation npm install react-nat
Windows10環境下React Native打包的個人實踐
參考文件: ReactNative 中文網 ReactNactive qq群 搭建React Native for Android Windows開發環境 最近剛剛升級了win10,發現win10
開發一個基於React Native的簡易demo--視訊元件+佈局
一、視訊元件 yarn add --save react-native-video react-native link 編碼 import Video from 'react-native-video'; ... <Video r
React-Native移動應用自動化測試框架Detox簡介
經過開發的鼎力相助,終於把RN的自動化測試框架研究通過了,目前環境已搭建並結合APP執行第一個Demo成功了。 1框架介紹(Detox) 它是為移動端APP打造的灰盒端到端自動化測試框架。 可用於React-Native開發的APP,使用js測試框架test或moc
基於React Native構建的仿京東客戶端(四)
實現產品列表卡檢視必須新增2個檔案ListItem.js和ProductList.js,請注意蘋果手機React-Native預設是不支援https協議的:ListItem.js檔案完整的程式碼如下:import React,{Component} from 'React';
React Native 實現基於react-native-tab-navigator庫Tab切換封裝
react-native-tab-navigator是一款Tab切換的庫,細心的讀者可能注意到了對於TabNavigator.Item選項卡部分,程式碼功能上基本上是重複的,對此,我們能不能對這種有相同功能的程式碼進行二次封裝呢? 程式碼示例 新建專
基於React Native構建的仿京東客戶端(三)
ImageButton.js檔案完整的程式碼如下:import React, { Component } from 'react';import { StyleSheet, Text, View, Image, TouchableWithoutFeedback,}
網易大資料平臺架構實踐分享!
隨著網易雲音樂、新聞、考拉、嚴選等網際網路業務的快速發展,網易開始加速大資料平臺建設,以提高資料獲取速度,提升資料分析效率,更快發揮資料價值。 本次演講主要分享網易如何圍繞和改造開源技術,以產品化思維打造網易自己的大資料平臺, 也會分享一下網易在大資料平臺構建和支撐網際網路業
一個基於React Native實現的美食類APP。
iShiWuPai https://github.com/ljunb/react-native-iShiWuPai iShiWuPai是基於React Native實現的展示型美食類APP。該分支針對原生新版食物派開發,主要針對Mobx練習(仍未完全遷移,所以存在部分R
基於React Native構建的仿京東客戶端(五)如何實現首頁 分類 發現 購物車 我的 Tab導航頁面
新建4個用紅色方框標識的檔案,如下圖所示:myths-Mac:JdApp myth$ yarn add react-native-tab-navigatorCartPage.js檔案完整的程式碼如下:import React, { Component } from 'reac
基於react-native-swiper 封裝的bannerView
使用 <BannerView defaultImage={constants.default_img} images={this.state.bannerData}