React Native Versions
RN 里面有很多个个版本号
package.json
里面定义的version
。android/app/build.gradle
里面定义的versionName
和versionCode
。ios/YOURAPP/Info.plist
里面定义的CFBundleShortVersionString
和CFBundleVersion
。- 如果你使用 code-push 的话,还有一个 code-push 自己的版本号,叫做
Label
一般是v
开头的。
这几个版本号都有用,需要有规划的使用。我的经验如下。
- 统一
version
,versionName
,CFBundleShortVersionString
,使用类似x.y.z
这样的格式,升级的时候都一起升级,每次发布这个版本前都会在 git 打一个 tag。这个是用来表示用户看到的 native 的版本。这样你的 app 在 ios 和 android 的市场里面,同一个版本的,一般就是同一套代码打包的, versionCode
和CFBundleVersion
各自表示各平台软件的真实版本,可能会出现同一个 1 里面的版本的情况下,这个有多个的情况。一般的应用市场发布的时候,也是认这个版本号的。这个编号只增不减,原则上每次打包都增加,不管代码有无变更。如果使用了 code-push,那还 1 里面的版本号还需要遵守一个原则:
- 如果 native 代码有变更,那需要增加
x.y
,比如可以从1.0
变成1.1
也可以是变成2.0
。 - 如果只是 js 代码更新,那只增加
z
,其他不变,同时 code-push 发布的时候,使用-t
指定 target version 为x.y.0 ~ x.y.z
这样的形式。
- 如果 native 代码有变更,那需要增加
基于上面的设置,实际一个 app 的版本号就是类似于 1.2.2(111)-v23
或者 1.2.2(111)-un
这样的形式。 1.2.2
表示 native 版本, 111
是编译版本, v23
是 codepush 的版本,如果没更新 codepush 那可能是 un
。 1.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 的版本号了。