我们都知道ReactNative的一个好处就是不用发布安装包即可进行热更新,依此来修复一些线上bug。本文就简述一下自主搭建服务的过程。
准备工作
热更新包括以下几点:
1、代码管理仓库code-push及其管理版本的方法。
2、基于mysql的服务器code-push-server。
3、其他如安装code-push使用的node.js、开发使用的webstorm等可自行了解下载。
安装code-push-server
安装mysql
mysql下载地址
下载之后直接一键安装即可。安装完成之后,在系统偏好设置中会看到MySQL的图标。
点击图标进去可以控制开启、关闭服务。
mysql5.6版本默认root密码为空,5.7为了安全会有一个初始化的密码,使用初始化密码登陆之后需要更改密码:
mysql -u root -p //回车之后输入密码
set password = password('输入你的新密码'); //每行命令要以分号作为结束语
MySQL的常用命令:
登陆mysql:
mysql -uroot -p//输入密码后即可进入到mysql中
显示数据库列表:
show databases;//
显示苦中的数据表:
use ; //use mysql;
show tables;
显示数据表结构:
describe ;
建库与删库:
create database ;
drop database ;
创建建表:
use ;
create table (字段列表);
删除表:
drop table ;
清空表中记录:
delete from where 1=1;//where 后面跟判断条件
显示表中的记录:
select * from where 1=1;//where 后面跟判断条件
更新表内容:
update set XXX=XXX where XXX= XXX;
安装code-push-server
code-push-server已经开源,且提供npm安装,我们搭建本地服务需要更改一些配置等信息,所以使用源代码比较合适,code-push-server git地址。
1、下载源代码
git clone https://github.com/lisong/code-push-server.git
然后进入code-push-server的根目录,执行npm install
2、更改配置信息
主要修改根目录下config/config.js
中的信息使其可以连上我们的mysql数据库。
db: {
username: process.env.RDS_USERNAME || "root",
password: process.env.RDS_PASSWORD || "111111",//这是我的密码
database: process.env.DATA_BASE || "codepush",
host: process.env.RDS_HOST || "127.0.0.1",
port: process.env.RDS_PORT || 3306,
dialect: "mysql",
logging: true
},
然后初始化数据库,需要在根目录下执行以下命令:
./bin/db init --dbhost localhost --dbuser root --dbpassword #初始化mysql数据库
执行完之后,可以查看一下mysql的数据库中是否已经有相应的数据库:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| codepush |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
那个codepush就是。
3、配置服务器文件存储
依旧在config/config.js
中修改:
在code-push-server中新建两个文件夹:data、storage:
// Config for local storage when storageType value is "local".
local: {
// Binary files storage dir, Do not use tmpdir and it's public download dir.
storageDir: process.env.STORAGE_DIR || "/XXX/code-push-server/storage",//storeage的文件路径
// Binary files download host address which Code Push Server listen to. the files storage in storageDir.
downloadUrl: process.env.LOCAL_DOWNLOAD_URL || "http://ip:3000/download",//将ip改为本地地址
// public static download spacename.
public: process.env.PUBLIC || '/download'
},
common: {
/*
* tryLoginTimes is control login error times to avoid force attack.
* if value is 0, no limit for login auth, it may not safe for account. when it's a number, it means you can
* try that times today. but it need config redis server.
*/
tryLoginTimes: 0,
// CodePush Web(https://github.com/lisong/code-push-web) login address.
//codePushWebUrl: "http://localhost:3001/login",
// create patch updates's number. default value is 3
diffNums: 3,
// data dir for caclulate diff files. it's optimization.
dataDir: process.env.DATA_DIR || "/XXX/code-push-server/data",//data的目录地址
// storageType which is your binary package files store. options value is ("local" | "qiniu" | "s3")
storageType: process.env.STORAGE_TYPE || "local",//将 storageType改为 local
// options value is (true | false), when it's true, it will cache updateCheck results in redis.
updateCheckCache: false
},
4、以上启动完成后可以启动服务:
./bin/www
可以通过本机浏览器:http://127.0.0.1:3000查看,默认密码是admin/123456
配置ReactNative项目工程
服务器搭建好了,需要本地开始连接能够连接服务器,本地项目配置步骤如下:(以code-push的Demo为例)
ReactNative中的配置
在reactnative的项目的package.json中添加对于的依赖
"dependencies": {
"babel-preset-react-native": "^1.9.2",
"metro-bundler": "^0.13.0",
"react": "16.0.0-beta.5",
"react-native": "^0.49.3",
"react-native-code-push": "file:../../"//这个地方是因为demo中有react-native-code-push的源代码,所以直接是文件路径,也可以使用版本号,然后调用npm install
},
引入react-native-code-push
之后,具体如何使用code-push的方法,可以参考CodePushDemoApp/App.js
中的代码。
原生APP中的配置
在com.codepushdemoapp/MainApplication中配置codepush的key以及服务器地址:
@Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage(),
new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG,getResources().getString(R.string.reactNativeCodePush_androidDeploymentServer))
);
}
对应string中的内容如下:
Jhtf0PNpaYMKYOeLrdkh0wTIaITw4ksvOXqog
http://10.40.31.241:3000/ //这个地方是服务器地址,不要写错了哦
CodePushDemoApp
其中上面的reactNativeCodePush_androidDeploymentKey
是在code-push上创建应用之后才有的。
这样配置之后,运行ReactNative项目,就会自动去服务器检查是否有新版本,是否需要更新等一系列流程会在后续详细分析。
安装Code-Push
有了服务和客户端,有新的版本如何发布到服务器呢,这个时候需要code-push了。
安装code-push
使用node.js安装:
npm install -g code-push-cli
等待运行完即可。
创建CodePush账号
CodePush的账号就是那个admin/123456,使用code-push login ip
code-push login http://127.0.0.1:3000/ //不加地址默认打开微软的地址
code-push logout//退出登陆
code-push access-key ls //列出登陆的token
code-push access-key rm //删除某个 access-key
打开登陆界面,输入账号密码后获取token,在cmd中输入token后即可登录。
AnonyPer:CodePushDemoApp XX$ code-push login http://127.0.0.1:3000/
A browser is being launched to authenticate your account. Follow the instructions it displays to complete your login.
Enter your access key: EgpwtTIaYTrJ3Deyf6RR2GfOo4it4ksvOXqog
Successfully logged-in. Your session file was written to /Users/XX/.code-push.config. You can run the code-push logout command at any time to delete this file and terminate your session.
AnonyPer:CodePushDemoApp XX$
其他的命令需要在登陆状态下执行。
在CodePush上注册APP
code-push app add // 可以使用code-push app -help查看相关帮助信息
AnonyPer:~ XX$ code-push app add Test-android
Successfully added the "Test-android" app, along with the following default deployments:
┌────────────┬───────────────────────────────────────┐
│ Name │ Deployment Key │
├────────────┼───────────────────────────────────────┤
│ Production │ qDeJFIX74XhAuBrAFM9r0xElsBTk4ksvOXqog │
├────────────┼───────────────────────────────────────┤
│ Staging │ Td9SNfIH9qLxQk2X6yCOMFw4wd8B4ksvOXqog │
└────────────┴───────────────────────────────────────┘
AnonyPer:~ XX$
这样就得到上面原生string.xml中需要的key值。Production:生产环境,Staging:开发环境。
其他code-push app 命令:
AnonyPer:~ XX$ code-push app -HELP
Usage: code-push app
命令:
add Add a new app to your account
remove Remove an app from your account
rm Remove an app from your account
rename Rename an existing app
list Lists the apps associated with your account
ls Lists the apps associated with your account
transfer Transfer the ownership of an app to another account
选项:
-v, --version 显示版本号 [布尔]
AnonyPer:~ XX$
发布更新到服务器
app已经创建好了,其他的也已经配置好了,就差发布一个更新版本来进行测试了,发布到code-push服务器上的是bundle文件,所以需要先把js文件打包成bundle文件,需要使用到react-native的命令:
在ReactNative项目中执行命令:
react-native bundle --platform 平台 --entry-file 启动文件 --bundle-output 打包js输出文件 --assets-dest 资源输出目录 --dev 是否调试
如下:
mkdir bundles
react-native bundle --platform android --entry-file index.android.js --bundle-output ./bundles/index.android.bundle --dev false
打完包之后就可以发布到服务器上了,具体命令:
AnonyPer:~ XX$ code-push release -HELP
Usage: code-push release [options]
选项:
--deploymentName, -d Deployment to release the update to [字符串] [默认值: "Staging"]
--description, --des Description of the changes made to the app in this release [字符串] [默认值: null]
--disabled, -x Specifies whether this release should be immediately downloadable [布尔] [默认值: false]
--mandatory, -m Specifies whether this release should be considered mandatory [布尔] [默认值: false]
--noDuplicateReleaseError When this flag is set, releasing a package that is identical to the latest release will produce a warning instead of an error [布尔] [默认值: false]
--rollout, -r Percentage of users this release should be available to [字符串] [默认值: "100%"]
-v, --version 显示版本号 [布尔]
示例:
release MyApp app.js "*" Releases the "app.js" file to the "MyApp" app's "Staging" deployment, targeting any binary version using the "*" wildcard range syntax.
release MyApp ./platforms/ios/www 1.0.3 -d Production Releases the "./platforms/ios/www" folder and all its contents to the "MyApp" app's "Production" deployment, targeting only the 1.0.3 binary version
release MyApp ./platforms/ios/www 1.0.3 -d Production -r 20 Releases the "./platforms/ios/www" folder and all its contents to the "MyApp" app's "Production" deployment, targeting the 1.0.3 binary version and rolling out to about 20% of the users
然后就可以到打开ReatNative的app来进行验证了。
ps: 使用code-push的命令也可以查看部署的信息:
AnonyPer:~ XX$ code-push deployment ls -help
Usage: code-push deployment ls [options]
选项:
--format Output format to display your deployments with ("json" or "table") [字符串] [默认值: "table"]
--displayKeys, -k Specifies whether to display the deployment keys [布尔] [默认值: false]
-v, --version 显示版本号 [布尔]
示例:
deployment ls MyApp Lists the deployments for app "MyApp" in tabular format
deployment ls MyApp --format json Lists the deployments for app "MyApp" in JSON format
code-push deployment ls xxxxx --displayKeys
┌────────────┬───────────────────────────────────────┬───────────────────────────────┬───────────────────────┐
│ Name │ Deployment Key │ Update Metadata │ Install Metrics │
├────────────┼───────────────────────────────────────┼───────────────────────────────┼───────────────────────┤
│ Production │ sBPAKWbFsEfBPhlRu4aGU6icx4iC4ksvOXqog │ No updates released │ No installs recorded │
├────────────┼───────────────────────────────────────┼───────────────────────────────┼───────────────────────┤
│ Staging │ 2PGXVsu3YiHohnJoaHaesrY49dud4ksvOXqog │ Label: v15 │ Active: 12% (2 of 17) │
│ │ │ App Version: 4.2.0 │ Total: 2 │
│ │ │ Mandatory: No │ │
│ │ │ Release Time: Dec 27, 2017 │ │
│ │ │ Released By: [email protected] │ │
└────────────┴───────────────────────────────────────┴───────────────────────────────┴───────────────────────┘
理论上到此就应该结束了,但是顺便提一点:
1、code-push发布应用步骤上是需要先把本地js文件打包成bundle文件,然后再发布,同时code-push也提供了一个整合命令:自动转换为bundle文件并发布到服务器:code-push release-react
AnonyPer:~ XX$ code-push release-react -HELP
Usage: code-push release-react [options]
选项:
--bundleName, -b Name of the generated JS bundle file. If unspecified, the standard bundle name will be used, depending on the specified platform: "main.jsbundle" (iOS), "index.android.bundle" (Android) or "index.windows.bundle" (Windows) [字符串] [默认值: null]
--deploymentName, -d Deployment to release the update to [字符串] [默认值: "Staging"]
--description, --des Description of the changes made to the app with this release [字符串] [默认值: null]
--development, --dev Specifies whether to generate a dev or release build [布尔] [默认值: false]
--disabled, -x Specifies whether this release should be immediately downloadable [布尔] [默认值: false]
--entryFile, -e Path to the app's entry Javascript file. If omitted, "index..js" and then "index.js" will be used (if they exist) [字符串] [默认值: null]
--gradleFile, -g Path to the gradle file which specifies the binary version you want to target this release at (android only). [默认值: null]
--mandatory, -m Specifies whether this release should be considered mandatory [布尔] [默认值: false]
--noDuplicateReleaseError When this flag is set, releasing a package that is identical to the latest release will produce a warning instead of an error [布尔] [默认值: false]
--plistFile, -p Path to the plist file which specifies the binary version you want to target this release at (iOS only). [默认值: null]
--plistFilePrefix, --pre Prefix to append to the file name when attempting to find your app's Info.plist file (iOS only). [默认值: null]
--rollout, -r Percentage of users this release should be immediately available to [字符串] [默认值: "100%"]
--sourcemapOutput, -s Path to where the sourcemap for the resulting bundle should be written. If omitted, a sourcemap will not be generated. [字符串] [默认值: null]
--targetBinaryVersion, -t Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3). If omitted, the release will target the exact version specified in the "Info.plist" (iOS), "build.gradle" (Android) or "Package.appxmanifest" (Windows) files. [字符串] [默认值: null]
--outputDir, -o Path to where the bundle and sourcemap should be written. If omitted, a bundle and sourcemap will not be written. [字符串] [默认值: null]
-v, --version 显示版本号 [布尔]
示例:
release-react MyApp ios Releases the React Native iOS project in the current working directory to the "MyApp" app's "Staging" deployment
release-react MyApp android -d Production Releases the React Native Android project in the current working directory to the "MyApp" app's "Production" deployment
release-react MyApp windows --dev Releases the development bundle of the React Native Windows project in the current working directory to the "MyApp" app's "Staging" deployment
2、code-push是一个代码管理仓库,也可以适用于cordova的更新。
3、-help是一个好东西。