1. 程式人生 > >實現 React Naitve 熱更新 (client && server) 客戶端以及伺服器端

實現 React Naitve 熱更新 (client && server) 客戶端以及伺服器端

目前針對react native 熱更新的方案比較成熟的選擇有microsoft公司的code-push 傳送門,與react-native 中文網的pushy 傳送門

本文選擇code-push 用來進行對react-native 實現熱更新,code-push 包含client端的配置,預設code-push 使用的伺服器地址為微軟的伺服器,但是在國內的網速不是太好。因此可以使用code-push-server 搭建自己的伺服器。本文主要介紹了實現熱更新 client 和 server 端的配置。

1.react native 熱更新 客戶端配置
1.首先全域性安裝code-push-cli

npm install -g code-push-cli

2.然後註冊一個code-push 賬號(可使用github賬號)

code-push register

3.註冊成功後將獲取的token在當前命令列輸入並回車 (如下)

Enter your token from the browser:  b0c9ba1f91dd232xxxxxxxxxxxxxxxxx
#成功提示如下方
Successfully logged-in. Your session file was written to /Users/huanghuanlai/.code-push.config. You can run the code-push logout command at any time to delete this file and terminate your session.

如使用自己搭建的code-push-server 可忽略 2 ,3 步驟 並使用以下命令登入到code-push-server

登入可採用以下命令

code-push login  http://***.***.***.***

4.使用code-push 新增一個 app

code-push app add AppName android react-native

新增成功後

code-push app add AppName android react-native
#成功提示如下方
Successfully added the "dounineApp-android" app, along with the following default deployments:
┌────────────┬──────────────────────────────────────────────────────────────────┐
│ Name       │ Deployment Key                                                   │
├────────────┼──────────────────────────────────────────────────────────────────┤
│ Production │ PZVCGLlVW-0FtdoCF-3ZDWLcX58L6dec4087-57cf-4c9d-b0dc-ad38ce431e1d │
├────────────┼──────────────────────────────────────────────────────────────────┤
│ Staging    │ T0NshYi9X8nRkIe_cIRZGbAut90a6dec4087-57cf-4c9d-b0dc-ad38ce431e1d │

5.在自己專案中安裝react-native-code-push

npm install react-native-code-push --save

6.將安裝的包進行link

react-native link react-native-code-push
Scanning folders for symlinks in /Users/huanghuanlai/dounine/oschina/dounineApp/node_modules (8ms)
? What is your CodePush deployment key for Android (hit <ENTER> to ignore) T0NshYi9X8nRkIe_cIRZGbAut90a6dec4087-57cf-4c9d-b0dc-ad38ce431e1d

#將剛才新增的Android App的Deployment Key複製貼上到這裡,複製名為Staging測試Deployment Key。

rnpm-install info Linking react-native-code-push android dependency 
rnpm-install info Android module react-native-code-push has been successfully linked 
rnpm-install info Linking react-native-code-push ios dependency 
rnpm-install WARN ERRGROUP Group 'Frameworks' does not exist in your Xcode project. We have created it automatically for you.
rnpm-install info iOS module react-native-code-push has been successfully linked 
Running ios postlink script
? What is your CodePush deployment key for iOS (hit <ENTER> to ignore) IjC3_iRGEZE8-9ikmBZ4ITJTz9wn6dec4087-57cf-4c9d-b0dc-ad38ce431e1d

此時為app 生成key的過程已完成,現需要在自己的專案中加入生成的key ,如果要採用自己的server需要配置伺服器的地址。
需要檢查如下資訊 在執行react-native link 命令後 會將相關的依賴進入引入。正常情況下link 會幫助我們完成以下操作,但有時並沒有完全引入需要自己檢查。

(1) 在 android/app/build.gradle檔案裡面是否包含如下程式碼:

apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"  

(2) 在/android/settings.gradle中是否包含如下程式碼:

include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

(3) 在 android/app/build.gradle 是否包含

compile project(':react-native-code-push')

個人修改
在android/app/src/main/java/MainApplication 中
預設的程式碼我在編譯後報錯,如下,(如無報錯可不用修改)

new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG),

修改後 (此時預設的為微軟的熱更新服務地址)

new CodePush("", MainApplication.this, BuildConfig.DEBUG),

如自己搭建的server 則忽略上面的修改,需要新增自己server的地址 如下
修改連結自己的熱更新伺服器(第一個引數為自己當前應用生成的key,最後一個引數為熱更新伺服器地址)

new CodePush("自己應用的key", MainApplication.this, BuildConfig.DEBUG,"http://***.***.***.***:3000/"),

在自己的專案的入口檔案引入react-code-push 並寫入檢測更新與使用者進行更新操作的邏輯程式碼
個人在app.js中修改

#先引入專案包
import codePush from "react-native-code-push";
#以下為自己的升級邏輯程式碼(放到入口檔案中)
    codePush.checkForUpdate(deploymentKey).then((update) => {
      if (!update) {
        console.log('已是最新版本',update)
      } else {
          codePush.sync({
                  deploymentKey: deploymentKey,
                  updateDialog: {
                      optionalIgnoreButtonLabel: '稍後',
                      optionalInstallButtonLabel: '立即更新',
                      optionalUpdateMessage: '有新版本了,是否更新?',
                      title: '更新提示'
                  },
                  installMode: codePush.InstallMode.IMMEDIATE,

              },
              (status) => {
                  switch (status) {
                      case codePush.SyncStatus.DOWNLOADING_PACKAGE:
                          console.log("DOWNLOADING_PACKAGE");
                          break;
                      case codePush.SyncStatus.INSTALLING_UPDATE:
                          console.log(" INSTALLING_UPDATE");
                          break;
                  }
              },
              (progress) => {
                  console.log(progress.receivedBytes + " of " + progress.totalBytes + " received.");
              }
          );
      }
})

code-push release-react <appName> <platform>
[--bundleName <bundleName>]
[--deploymentName <deploymentName>]
[--description <description>]
[--development <development>]
[--disabled <disabled>]
[--entryFile <entryFile>]
[--gradleFile <gradleFile>]
[--mandatory]
[--noDuplicateReleaseError]
[--outputDir <outputDir>]
[--plistFile <plistFile>]
[--plistFilePrefix <plistFilePrefix>]
[--sourcemapOutput <sourcemapOutput>]
[--targetBinaryVersion <targetBinaryVersion>]
[--rollout <rolloutPercentage>]
[--privateKeyPath <pathToPrivateKey>]
[--config <config>]

釋出之前需要將專案打包

# 執行打包
gradlew.bat assembleRelease

然後再專案的根目錄下執行命令釋出
(通過檢視釋出配置項,可看到支援指定檔案釋出,感興趣的同學可研究其釋出命令)

code-push release-react 應用名稱 android -m true --des '描述' -t 版本

如無報錯資訊則釋出成功,此時開啟應用可檢視到更新的提示。

2. React Native 熱更新server端配置 (搭建 code-push-server)

  • 所需環境 node
  • 所需軟體 mysql pm2
  • 伺服器環境 RedHat

1.首先搭建node 環境採用 nvm安裝
安裝步驟

# 下載安裝NVM指令碼
>>>curl https://raw.githubusercontent.com/creationix/nvm/v0.13.1/install.sh | bash
>>>source ~/.bash_profile

# 列出npm的版本號
>>>nvm list-remote

# 選擇其一安裝即可, vn.n.n是版本號,此步驟耗時最久
>>>nvm install vn.n.n

# 檢視已安裝的版本
>>>nvm list

# 使用版本
>>>nvm use vn.n.n

# 設定為預設版本
>>>nvm alias default vn.n.n


通過此步驟我安裝的node版本為v8.11.3 npm 版本為5.6.0

2.安裝mysql

#下載,在這裡使用的是命令列下載,也建議在圖形介面下載,然後上傳至伺服器
>>>wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm

#使用rpm安裝
>>>rpm -ivh mysql-community-release-el7-5.noarch.rpm

#使用yum安裝mysql-community-server
>>>yum install mysql-community-server

#啟動服務
>>>service mysqld start

#進入mysql,第一次進入無密碼
>>>mysql -u root -p

#命令列變成如下
mysql> 

配置mysql

#進入配置檔案,若未安裝vim,建議先使用命令yum install vim安裝vim
>>>vim /etc/my.cnf

#最後加上編碼配置
[mysql]
default-character-set =utf8

#此處字元編碼必須和/usr/share/mysql/charsets/Index.xml中一致。
#不過一般情況下使用的都是utf8

設定密碼

#下面三種方法需要進入mysql
>>>mysql -u root -p

#方法一
mysql>insert into user(host,user,password) values('%','user_name',password("password");
#方法二
mysql>set password for user_name = password("password");
#方法三
mysql>grant all on *.* to [email protected]% identified by "password";

#下面這一種方法可直接在shell下設定密碼
>>>mysqladmin -u root password "password"

遠端連線

#進入mysql
>>>mysql -u root -p

#把在所有資料庫的所有表的所有許可權賦值給位於所有IP地址的root使用者。
mysql> grant all privileges on *.* to [email protected]'%'identified by "password";

3.下載code-push-server 並配置

# 下載原始碼
>>>git clone https://github.com/lisong/code-push-server

# 進入原始碼目錄並安裝相應模組
>>>cd code-push-server && npm install

# 修改配置檔案
>>>vim config/config.js

資料庫配置檔案

db: {
    username: "root",
    password: null,
    database: "codepush",
    host: "127.0.0.1",
    dialect: "mysql"
  },
  //七牛雲端儲存配置 當storageType為qiniu時需要配置
  qiniu: {
    accessKey: "",
    secretKey: "",
    bucketName: "",
    downloadUrl: "" //檔案下載域名地址
  },
  //阿里雲端儲存配置 當storageType為oss時需要配置
  oss: {
    accessKeyId: "",
    secretAccessKey: "",
    endpoint: "",
    bucketName: "",
    prefix: "", // 物件Key的字首,允許放到子資料夾裡面
    downloadUrl: "", // 檔案下載域名地址,需要包含字首
  },
  //檔案儲存在本地配置 當storageType為local時需要配置

檔案儲存部分

 local: {
    storageDir: "/Users/tablee/workspaces/storage",
    //檔案下載地址 CodePush Server 地址 + '/download' download對應app.js裡面的地址
    downloadUrl: "http://localhost:3000/download",  #本地伺服器地址
    // public static download spacename.
    public: '/download'
  },
  jwt: {
    // 登入jwt簽名金鑰,必須更改,否則有安全隱患,可以使用隨機生成的字串
    // Recommended: 63 random alpha-numeric characters
    // Generate using: https://www.grc.com/passwords.htm
    tokenSecret: 'INSERT_RANDOM_TOKEN_KEY'
  },
  common: {
    dataDir: "/Users/tablee/workspaces/data",
    //選擇儲存型別,目前支援local,oss,qiniu,s3配置
    storageType: "local"
  },


初始化資料庫

# 初始化資料庫
>>>./bin/db init --dbhost localhost --dbuser root  --dbpassword password --dbport 3306

# 初始化資料庫確保不報錯才能啟動服務
>>>./bin/www

# 若無報錯,則表示成功啟動,預設埠為3000

可在本地開啟瀏覽器進行檢驗,輸入ip:3000 檢視code-push-server 是否正常執行

本人通過pm2 管理 code-push-server 服務

# 安裝pm2 
npm install -g pm2 
# 通過 pm2 啟動服務並命名
pm2 start ./bin/www --name code-push-server
# 檢視當前服務程序
pm2 list
-------------------------------------------------------
──────────────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name         │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user │ watching │
├──────────────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│ code-push-server │ 1  │ 0.5.2   │ fork │ 4282 │ online │ 1       │ 0s     │ 0%  │ 11.5 MB   │ root │ disabled │

此時server 配置已經完成,可直接進行熱更新部署。