RN精進筆記(六)RN打離線包篇

b10l07發表於2018-06-01

React-Native打離線包

RN-App專案中js程式碼和native程式碼,其中js程式碼的打包是動態的,打成jsbundle的過程中,js會將自己所需要的所有的檔案(這裡指你的js業務程式碼中的require或者import部分)匯入到bundle中。

RN-App專案的結構

一個完整的RN-app程式通常包含以下幾個部分:

  1. native程式碼部分-objc部分。引入react-native框架,程式碼中新增的部分是Library部分。大小在2.2M左右,至於打成ipa包增大估計在6M~8M以內。
pod 'React', :path => './node_modules/react-native', :subspecs => [
'Core',
'RCTImage',
'RCTNetwork',
'RCTText',
'RCTWebSocket',
'ART',
'RCTActionSheet',
'RCTGeolocation',
'RCTPushNotification',
'RCTSettings',
'RCTVibration',
'RCTLinkingIOS',
]
  1. js程式碼部分-rn程式碼依賴的第三方庫業務程式碼等。這部分程式碼是通過線上下載的程式碼,不會打到ipa包中,可以通過熱載入的方式從服務端載入。這部分如果採用壓縮方式打包,大小不會超過1M。js打成bundle包(可以檢視一下bundle包的程式碼,發現裡面全是壓縮了的js),然後放到伺服器上,下載到APP本地更新。
1.js業務程式碼:這部分程式碼很少
2.react-native程式碼:這部分程式碼就是facebook的開源框架的js程式碼,在打成bundle包時,不用擔心所有資原始檔都會打包,js採用的是動態打包方式,只會將自身require或者import的部分打入bundle 包。
3.依賴的第三方庫:這裡指的是我們的js業務程式碼可能需要依賴一些優秀的react開源框架,如react-native-navbar這種導航欄第三方庫,通過require載入,也會載入到我們的bundle包。有一個要注意的是,如果依賴的第三方庫不是純js程式碼的話,就不能實現熱更新。
  1. 圖片資源部分。這部分通過打包命令打包時生成asset資料夾。
打包命令說明
react-native bundle
Options:
--entry-file Path to the root JS file, either absolute or relative to JS root [required]
--platform Either "ios" or "android"
--transformer Specify a custom transformer to be used (absolute path) [default: "/Users/babytree-mbp13/projects/xcodeProjects/AwesomeProject/node_modules/react-native/packager/transformer.js"]
--dev If false, warnings are disabled and the bundle is minified [default: true]
--prepack If true, the output bundle will use the Prepack format. [default: false]
--bridge-config File name of a a JSON export of __fbBatchedBridgeConfig. Used by Prepack. Ex. ./bridgeconfig.json
--bundle-output File name where to store the resulting bundle, ex. /tmp/groups.bundle [required]
--bundle-encoding Encoding the bundle should be written in (https://nodejs.org/api/buffer.html#buffer_buffer). [default: "utf8"]
--sourcemap-output File name where to store the sourcemap file for resulting bundle, ex. /tmp/groups.map
--assets-dest Directory name where to store assets referenced in the bundle
--verbose Enables logging [default: false]
打包步驟
  1. cd到工程目錄(index.ios.js&package.json存放的目錄),執行打包命令.
react-native bundle --minify --entry-file ./index.ios.js --platform ios --bundle-output ./main.ios.jsbundle --assets-dest ./
  1. 命令執行完生成.bundle檔案

  2. 在Xcode中新增.bunldeassets,必須是Create folder references的方式。

  3. 修改jsCodeLocation

jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index.ios" withExtendsion:@"jsbundle"];
  1. 另外一種打包命令,程式執行時執行該命令。
curl 'http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.bundle?platform=ios' -o main.jsbundle
或者
curl 'http://localhost:8081/index.ios.bundle?dev=false&minify=true&platform=ios' -o main.jsbundle
  1. 檢視專案中的main.jsbundle或者main.os.jsbundle發現bundle檔案裡是壓縮了的js程式碼,該部分程式碼包括 業務js+react-native程式碼+依賴第三方程式碼
打包遇到的問題
  1. 離線包如果開啟了chrome除錯,hui訪問除錯伺服器,而且會一直loading不出來。一直提示。。。
Loading from pre-bundled file...
  1. 如果bundle的名字是main.jsbundle,app會一直讀取舊的,改名就好了。。。非常奇葩的問題,我重新刪了app,clean工程都沒用,就是不能用main.jsbundle這個名字。這個問題貌似沒遇到過。。。

  2. 必須用Create folder references【藍色資料夾圖示】的方式引入圖片的assets,否則引用不到圖片

  3. 執行bundle命令之前,要保證相關的資料夾都存在

  4. To disable the developer menu for production builds:

For iOS open your project in Xcode and select Product → Scheme → Edit Scheme... (or press ⌘ + <). Next, select Run from the menu on the left and change the Build Configuration to Release.
  1. over
使用react-native-webpack-server打包

重要,待補充

React-Native釋出與熱更新

打包完成之後,要實現熱更新,還需要在原生程式碼中做一些邏輯處理,簡單流程如下:

  1. 首先將上一步輸出的main.jsbundle檔案放到伺服器上,可以達成zip包下載,進一步壓縮檔案大小。
  2. 在App啟動的時候,判斷RN程式碼是否有更新,若有更新,則將更新的包下載下來;若沒有更新,則不做處理。(這部分類似於現有的jspatch更新)。
  3. 有新的更新,在載入RN的入口處,將url指向新的檔案地址。
  4. 同時,為了保證安全性和下載流量,應將main.jsbundle用密碼壓縮,在下載下來之後,再進行解壓處理。
  5. over
React-Native增量更新

待補充

相關文章