備注
這是很久以前保存的文件,將原始的內(nèi)容放到這里以備不時之需。
目錄
1. 為什么要使用RN
1. 編程人員永遠的夢想
1. 一次編寫,到處運行之路
1. C/Java/Qt
2. write once, run everywhere
2. learn once, write everywhere
1. Chrome撐起的夢想
1. Electron/Chrome App
2. virtual-dom
1. 虛擬dom
3. React
1. Web
2. Native
2. 屏蔽了底層代碼, 學習成本低
1. 我的全棧工程師之路 => 21天精通React
3. 快速發(fā)版
4. 性能優(yōu)勢
5. 為什么不用Weex
1. 池建強的博客截圖
2. React Native Init
1. 初始框架的搭建
1. react-native init jumeiReactNative
2. 多項目的改造
1. 引入
3. React Native 工具包
1. Chrome Developer Tools
2. react-devtools
1. 安裝時需要在npmrc中指定electron地址: `ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/`
3. React Native工程化
1. 配置系統(tǒng)(接口開關(guān))
1. 平臺控制
1. 項目開關(guān)
1. 總開關(guān)
1. 失敗次數(shù)控制
1. 系統(tǒng)版本控制(Android/iOS)
1. Rom版本控制(安卓定制系統(tǒng), iOS具體版型(iOS6/7/8))
1. 客戶端版本控制
1. CPU版本控制
當檢測到可以開啟RN后, 由客戶端下載bundle包
2. Module同步(bundle包下載)
1. 調(diào)用接口,獲取最新bundle列表
1. 依次檢測本地是否已下載過bundle包
檢測標準:
1. 文件名相同
1. 版本號相同
1. 文件簽名相同
未下載 => 啟動下載流程
1. bundle下載
1. 下載失敗
1. 網(wǎng)絡(luò)異常
1. 存儲空間不足
1. 解壓縮失敗
1. 校驗不通過(文件hash不對, 文件名不對)
1. 下載成功
1. 校驗并保存文件
已下載 => 跳過
3. 啟動RN
1. 本地是否有對應(yīng)bundle
1. 存在 => 載入bundle
1. RN啟動
1. 活動流程是否正常(日常測試)
1. 原生通信是否正常, 是否可以正常調(diào)用原生功能(RN項目測試)
1. 檢查調(diào)用原生功能情況
1. 頁面跳轉(zhuǎn),返回,讀取本地存儲,本地通知,Dialog,Toast彈出
2. 不存在 => 降級啟動H5頁面
2. 日志記錄與上報
3. 測試過程中的Tips
4. 爬坑之路
2. 按路徑引入
3. setState
5. 資源推薦
1. [React Native標準文檔](http://reactnative.cn/docs/0.51/getting-started.html)
2. [React Native小書](https://hydrographer-vivian-23728.netlify.com/)
4. [React 樣式表手冊](https://shenbao.github.io/ishehui/html/RN%20%E5%9F%BA%E7%A1%80/React%20Native%20%E6%A0%B7%E5%BC%8F%E8%A1%A8%E6%8C%87%E5%8D%97.html#)
5. [React Native動畫進階(中文版)](https://future-challenger.gitbooks.io/react-native-animation/content/)
3. [構(gòu)建 F8 App / 官方React Native 開發(fā)指南](https://f8-app.liaohuqiu.net/tutorials/)
6. [Redux 中文文檔(勸退指南)](http://cn.redux.js.org/)
6. 劣勢
1. 還處于快速發(fā)展期, 頻繁更新
2. 性能和原生頁面畢竟還是有差距, 不能繪制過于復(fù)雜的動畫
正文
大家好, 今天由我和孫陽來為大家做一下React Native的分享. 在這次的分享里, 我會先簡單介紹一下React的相關(guān)知識和選用React Native的原因, 然后由孫陽來為我們詳細介紹下React Native具體的工程化過程, 最后會介紹一些項目實施中遇到的坑和相關(guān)的學習資源.
讓我們先從React開始. React是Facebook編寫的一套前端框架. 在React之前, 大家寫HTML的思路是按標簽去寫, p標簽a標簽之類的, 然后如果想寫一個復(fù)雜點的功能的話就需要把這些標簽全都摞起來, 一個個的調(diào)位置. 這種思路在標簽量小的情況下還好, 但是標簽量一大就會很難辦, 一大坨標簽密密麻麻擠一堆, 誰都維護不了. 當然了, 在真實工作中碰到這種問題我們也是有解決辦法的, 就是結(jié)構(gòu)化編程, 把標簽按功能拆分開, 每個功能區(qū)之間互相獨立互不影響, 這樣一個頁面無論再怎么復(fù)雜, 都可以通過拆分的方式把它分成一個個的小塊, 我們只要組織好這些小塊就行了. 如果我們再給這些小塊起一個專用的名字, 比如說組件 => vue1.0 就誕生了. 但為什么這個思路只是vue1.0 不是React呢, 因為在我們剛才的構(gòu)想里, 組件和網(wǎng)頁元素標簽還是一一對應(yīng)的, React比這更近一步, 他在組件和元素標簽之間引入了一層虛擬dom, 組件被映射成虛擬的dom結(jié)構(gòu), 然后再由框架將這些虛擬的dom元素轉(zhuǎn)換成真正的HTML標簽列表.
ok, 關(guān)鍵的地方來了. React的界面是由組件構(gòu)成的, 而我們知道安卓和iOS的界面也都是由和組件類似的控件構(gòu)成的, 那么, 有沒有可能利用虛擬dom這個中間層, 把React的組件給轉(zhuǎn)換成安卓和iOS的組件呢?如果再加上底層庫的配合, 讓js可以請求網(wǎng)絡(luò)/存儲數(shù)據(jù)/觸發(fā)彈窗/記錄日志的話, 對于純數(shù)據(jù)的展示, 是不是就可以直接用React去寫了呢? 當然, 這些問題我們現(xiàn)在都已經(jīng)知道答案了, 2015年4月, React Native第一版上線, React開始支持iOS平臺, 2015年9月, React Native正式支持Android的開發(fā). 至此, 如果你會寫React的話, 相當于你不光能寫網(wǎng)頁, 同時也能寫Android和iOS的應(yīng)用.
而且問題在于, 跟iOS和Android開發(fā)比起來, React確實要更簡單. 如果你是一個原生開發(fā)人員, 系統(tǒng)自帶的數(shù)據(jù)庫存儲要會, 文件系統(tǒng)結(jié)構(gòu)要會, 進程線程模型要知道, 事件模型要知道. 但是如果只是為了展示數(shù)據(jù)進行交互的話, 根本不需要了解這些系統(tǒng)底層的知識, 只要知道展示文本用Text組件, 展示圖片用Image組件就夠了. 而且, React發(fā)版速度也很快. 因為React 項目就是一個js文本文件, 發(fā)版的時候只要把這個文本文件傳到網(wǎng)上, 更新下配置就可以.
總結(jié)一下: 對于展示頁面來說, React 技術(shù)棧 入門簡單, 開發(fā)效率高(一次編寫, 三端運行), 發(fā)版速度快, 作為技術(shù)人員我們實際上沒什么理由不用React. 當然, 有同學可能會問, Vue技術(shù)棧下邊也有和React Native相同的Weex, 為什么我們不直接沿用現(xiàn)在前端的技術(shù)棧, 而是要用一個全新的React技術(shù)棧呢. 這就是React 的另一項優(yōu)點了: 社區(qū)大,坑少.
React 2013年首次對外發(fā)布, 15年推出Native框架, 現(xiàn)在京東, QQ, 去哪兒都在大量使用React Native相關(guān)的技術(shù)棧, 可以說是一套比較成熟的框架了. 但是基于Vue的Weex, 這個, 也不多說啥. 前段時間極客邦基于Weex推出了一款A(yù)pp, 這是他們在結(jié)項后的感謝辭: 感謝Weex團隊, 感謝張小龍幫忙協(xié)調(diào)資源, 然后在這么強的支持下, 極客時間項目整體延期, 10月17號iOS上線, 12月8號安卓才發(fā)布上線...然后, 如果我們的人脈沒有那么強, 請不動張小龍, 也找不到Weex開發(fā)組, 然后這樣的話, 你們都懂.
介紹完React Native, 我們來講下它的具體使用.
首先當然是執(zhí)行react-native init jumeiReactNative初始化項目, 然后npm install安裝依賴, react-native run-android 啟動debug模式. 這些官網(wǎng)上都有, 我這兒就不多說了.
重點要介紹的是這兩個地方:
- 首先, 我們來看下RN的代碼, 他這個就是React的代碼, 沒有其他多余的東西. 也就是說, React Native確實像他描述的一樣, 只要會寫React 就能寫React Native. 沒有其他學習成本
- 因為React Native的代碼只是一層皮, 他的本質(zhì)是被編譯好了的, 隨時可以修改的js, 因此React Native的代碼可以和普通的js代碼一樣調(diào)試, 而且還可以直接在Chrome瀏覽器里打日志, 單步調(diào)試. 就像這樣(開啟遠程調(diào)試功能, 展示Chrome瀏覽器下的日志打印和單步調(diào)試功能)
- 除了這些, 我們還可以直接用react-devtools查看組件的效果(展示react-devtools的效果). 不過這里有個小坑, 因為這個工具用到了electron, 而electron的安裝地址又被國家屏蔽了, 所以安裝工具的時候經(jīng)常會因為網(wǎng)絡(luò)異常失敗. 所以我們需要在系統(tǒng)的npmrc配置里指定electron的安裝源才行.
- 然后順帶講一下, 他這里的electron實際上跟我們的RN是一樣的, 也是提供一個殼, 然后里邊實際跑的是js代碼. 比如現(xiàn)在前端開發(fā)常用的VS Code 編輯器, 實際上就是用Chrome瀏覽器加上HTML畫出來的. 15年之后各種桌面系統(tǒng)的原生開發(fā)在事實上已經(jīng)停滯了, 現(xiàn)在新出的軟件都是用js+chrome瀏覽器外殼去實現(xiàn). React Native其實只是這種浪潮下的一個分支而已.
然后, 關(guān)于RN的基礎(chǔ)知識已經(jīng)講的差不多了, 下面讓我們請孫陽來為我們介紹下聚美RN的具體實施過程.
孫陽部分
ok, 孫陽分享完了測試的要點, 我來分享下RN項目在開發(fā)時的一些坑.
先是一個小坑:
- 按路徑引入
- react-native里有一個小問題, 就是它默認只能用相對路徑去引入模塊. 這樣就意味著我們在寫代碼的時候要寫一大堆的"../.."去回到根目錄, 而且代碼目錄越深".."就用的越多, 寫起來非常惡心.
- 不過RN提供了一個hack的方式, 就是我們可以通過在指定目錄下添加一個package.json的文件來給一個目錄指定模塊名, 比如, 我們可以在src目錄下添加一個package.json, 內(nèi)容是
{ "name": "src" }, 這樣src這個目錄就會被RN識別為src模塊, 以后引用的時候就可以直接引了 - 之所以說這是一個坑是因為這個解決方案在中文網(wǎng)絡(luò)里沒有, 是在Github的一個issue里找到的, 所以專門提一下
然后有一個狀態(tài)管理的大坑.
RN的樣式展示和邏輯代碼是分屬與兩個線程的. 當邏輯線程更新了組件狀態(tài), 樣式展示代碼就會根據(jù)新狀態(tài)去渲染組件. 這個看起來沒什么問題, 但是在實踐的時候出現(xiàn)了這種情況, 就是: 邏輯線程在更新完狀態(tài)之后自動退出, 然后RN所在的Activity也跟著被回收了回去, 這里沒問題, 但是因為線程之間的消息不同步, 然后輪到樣式展示線程的時候展示線程看到狀態(tài)有更新, 就直接去更新組件, 但是組件又不存在, 導致代碼Crash.
這其實很坑,因為檢測組件存不存在這種事屬于臟活,而且也是基礎(chǔ)功能, 應(yīng)該由框架自己負責.我當時沒想到RN發(fā)展了兩年連這個功能都沒做,所以也沒忘這塊考慮, 導致這一個bug找了半天. 不過這個bug最后是這么解決的: 我們加了一個onMounted信號量, 組件載入就設(shè)成true, 組件銷毀就改成false, 然后在每次更新狀態(tài)和更新組件前都檢測一下這個信號量, 如果為false就直接返回.這樣才算是解決了.
最后一點就是性能問題. 前面說了, RN雖然最后會被翻譯成原生代碼進行執(zhí)行, 但是畢竟經(jīng)過了一層虛擬dom中間層, 導致他的性能肯定會比真正的原生要差一點.因此RN不適合展示復(fù)雜的動畫, 這點需要注意.
好了, 最后再介紹一下RN的學習資源
首先是官方文檔, 這個不用說了, 從搭建環(huán)境到實際開發(fā), 肯定要經(jīng)常翻看的.
然后是React Native小書, 這是一本由中國開發(fā)者寫的RN介紹, 建議搭建完環(huán)境后就直接看這本書, 在引領(lǐng)入門方面寫的比文檔要好.
然后是RN支持的全部樣式表和RN的動畫手冊, 這塊前端同學在開發(fā)的時候肯定要翻的.
最后是一個Facebook官方的示例代碼, 和Redux使用指南. 官方示例這個就不說了, 直接看就行. Redux這個要說一下. 一般來說大型React系統(tǒng)都需要上Redux去管理組件的各種狀態(tài), 但是如果是小項目的話, 文檔和我的建議都是不要上這個, 對于我們平常用的小頁面來說, 它帶來的復(fù)雜度的提升會遠遠大于引入他所能獲得的在開發(fā)效率上的收益.
我們的分享講完了, 謝謝大家