React Native Versions

RN 里面有很多个个版本号

  1. package.json 里面定义的 version
  2. android/app/build.gradle 里面定义的 versionNameversionCode
  3. ios/YOURAPP/Info.plist 里面定义的 CFBundleShortVersionStringCFBundleVersion
  4. 如果你使用 code-push 的话,还有一个 code-push 自己的版本号,叫做 Label 一般是 v 开头的。

这几个版本号都有用,需要有规划的使用。我的经验如下。

  1. 统一 version, versionName, CFBundleShortVersionString ,使用类似 x.y.z 这样的格式,升级的时候都一起升级,每次发布这个版本前都会在 git 打一个 tag。这个是用来表示用户看到的 native 的版本。这样你的 app 在 ios 和 android 的市场里面,同一个版本的,一般就是同一套代码打包的,
  2. versionCodeCFBundleVersion 各自表示各平台软件的真实版本,可能会出现同一个 1 里面的版本的情况下,这个有多个的情况。一般的应用市场发布的时候,也是认这个版本号的。这个编号只增不减,原则上每次打包都增加,不管代码有无变更。
  3. 如果使用了 code-push,那还 1 里面的版本号还需要遵守一个原则:

    1. 如果 native 代码有变更,那需要增加 x.y ,比如可以从 1.0 变成 1.1 也可以是变成 2.0
    2. 如果只是 js 代码更新,那只增加 z ,其他不变,同时 code-push 发布的时候,使用 -t 指定 target version 为 x.y.0 ~ x.y.z 这样的形式。

基于上面的设置,实际一个 app 的版本号就是类似于 1.2.2(111)-v23 或者 1.2.2(111)-un 这样的形式。 1.2.2 表示 native 版本, 111 是编译版本, v23 是 codepush 的版本,如果没更新 codepush 那可能是 un1.2.2(111) 部分可以通过 RN 模块或者程序启动时候注入到 js 里面来, v23 部分可以使用 codepush 的 api 取。

一般我们以 package.json 里面的版本为准,android 可以让 gradle 读取这个文件自动变更版本, ios 需要自己写一个程序。

def getNpmVersion() {
    def inputFile = new File("../package.json")
    def packageJson = new JsonSlurper().parseText(inputFile.text)
    return packageJson["version"]
}

def getNpmVersionArray() { // major [0], minor [1], patch [2]
    def (major, minor, patch) = getNpmVersion().tokenize('.')
    return [Integer.parseInt(major), Integer.parseInt(minor), Integer.parseInt(patch)] as int[]
}

versionName "${versionMajor}.${versionMinor}.${versionPatch}"

ios 写程序用类似命令改 /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${PACKAGE_VERSION}" "ios/YOURAPP/Info.plist" 就可以。可以修改 package.json 增加 version

    "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start",
        "test": "jest",
        "lint": "node_modules/.bin/eslint app",
        "version": "./version-ios.sh",
        "precommit": "./pre-commit",
        "postinstall": "patch-package"
    },

使用 npm version 的时候就可以自动同步修改 ios,android 的版本号了。