mirror of
https://gitcode.com/gh_mirrors/re/react-native-pushy.git
synced 2025-09-18 02:16:11 +08:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
00c1eac457 | ||
![]() |
84ffaa7f5a | ||
![]() |
1e5d73c0d3 | ||
![]() |
df98736c3b | ||
![]() |
c654022300 | ||
![]() |
8a237845e2 | ||
![]() |
8b31779b07 | ||
![]() |
84fde13a79 | ||
![]() |
1e9650478d | ||
![]() |
7e11356cb9 | ||
![]() |
0eaf27aea9 | ||
![]() |
3353c16fa3 | ||
![]() |
93d2a6cccb | ||
![]() |
cfdc26f71d | ||
![]() |
b6a08a19c8 | ||
![]() |
ef53716df3 | ||
![]() |
551cbc33cc | ||
![]() |
56e6d790c1 | ||
![]() |
976cc5f218 | ||
![]() |
6fd04a1cc3 | ||
![]() |
31a0eadbbf | ||
![]() |
6f0755e571 | ||
![]() |
4099986a9c | ||
![]() |
48101bbd51 | ||
![]() |
1c2507e631 | ||
![]() |
b5e273deef | ||
![]() |
b55a40c92c | ||
![]() |
d23178a851 |
44
CHANGELOG.MD
Normal file
44
CHANGELOG.MD
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
### 最新更新
|
||||||
|
|
||||||
|
## 5.2.5
|
||||||
|
|
||||||
|
1. 改进windows端打更新包的兼容性(部分windows机器上会产生空ppk文件)
|
||||||
|
|
||||||
|
## 5.2.4
|
||||||
|
|
||||||
|
1. 支持RN 0.61的hermes(路径变化)
|
||||||
|
2. iOS端使用第三方的SSZipArchive以减少重名冲突
|
||||||
|
|
||||||
|
## 5.2.2
|
||||||
|
|
||||||
|
1. 修复一处导致iOS回滚的问题
|
||||||
|
|
||||||
|
## 5.2.1
|
||||||
|
|
||||||
|
1. 检测如果开启了hermes,则自动编译为hermes字节码格式
|
||||||
|
|
||||||
|
## 5.2.0
|
||||||
|
|
||||||
|
1. 添加typescript声明
|
||||||
|
2. 支持cocoapods
|
||||||
|
|
||||||
|
## 5.1.9
|
||||||
|
|
||||||
|
1. 重写bundle命令以提升版本兼容性
|
||||||
|
2. 改进命令行的输出样式
|
||||||
|
|
||||||
|
|
||||||
|
## 5.1.8
|
||||||
|
|
||||||
|
1. 服务器迁移到https
|
||||||
|
2. android支持64位
|
||||||
|
|
||||||
|
|
||||||
|
## 5.1.6
|
||||||
|
|
||||||
|
解决 Android 热更新后部分图片丢失问题:
|
||||||
|
|
||||||
|
同一个项目中放置了多个完全相同的文件,在 5.1.0 至 5.1.5 之间的版本中,更新后有时会出现其中的部分无法显示。此问题在 5.1.6 版本修复。
|
||||||
|
|
||||||
|
修复此问题涉及原生部分,需要重新打包。
|
26
README.md
26
README.md
@@ -2,32 +2,6 @@
|
|||||||
|
|
||||||
本组件是面向 React Native 提供热更新功能的组件,建议结合[Update 服务](https://update.reactnative.cn/)使用。
|
本组件是面向 React Native 提供热更新功能的组件,建议结合[Update 服务](https://update.reactnative.cn/)使用。
|
||||||
|
|
||||||
### 最新更新
|
|
||||||
|
|
||||||
5.1.6: 解决 Android 热更新后部分图片丢失问题:
|
|
||||||
|
|
||||||
同一个项目中放置了多个完全相同的文件,在 5.1.0 至 5.1.5 之间的版本中,更新后有时会出现其中的部分无法显示。此问题在 5.1.6 版本修复。
|
|
||||||
|
|
||||||
修复此问题涉及原生部分,需要重新打包。
|
|
||||||
|
|
||||||
5.1.0 以上的版本增加了如下的优化:
|
|
||||||
|
|
||||||
1. 在项目中图片较多时,Android 更新速度大幅提升,达到和 iOS 基本一致的更新速度。
|
|
||||||
2. Android 的更新移到了单独的线程,避免更新过程对 AsyncStorage 等原生异步模块的影响。
|
|
||||||
3. Android 的.so 文件长时间没有任何改动,因而加入了预编译好的文件,避免对 ndk 的依赖。
|
|
||||||
|
|
||||||
### 版本
|
|
||||||
|
|
||||||
因为 React Native 不同版本代码结构不同,因而请按下面表格对号入座:
|
|
||||||
|
|
||||||
| React Native 版本 | react-native-update 版本 |
|
|
||||||
| ----------------- | ------------------------ |
|
|
||||||
| 0.26 及以下 | 1.0.x |
|
|
||||||
| 0.27 - 0.28 | 2.x |
|
|
||||||
| 0.29 - 0.33 | 3.x |
|
|
||||||
| 0.34 - 0.45 | 4.x |
|
|
||||||
| 0.46 及以上 | 5.x |
|
|
||||||
|
|
||||||
### 优势
|
### 优势
|
||||||
|
|
||||||
1. 命令行工具&网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
1. 命令行工具&网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
||||||
|
@@ -135,13 +135,12 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
|||||||
loadField.set(instanceManager, loader);
|
loadField.set(instanceManager, loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Method recreateMethod = instanceManager.getClass().getMethod("recreateReactContextInBackground");
|
try {
|
||||||
|
instanceManager.recreateReactContextInBackground();
|
||||||
|
} catch(Throwable err) {
|
||||||
|
activity.recreate();
|
||||||
|
}
|
||||||
|
|
||||||
final ReactInstanceManager finalizedInstanceManager = instanceManager;
|
|
||||||
|
|
||||||
recreateMethod.invoke(finalizedInstanceManager);
|
|
||||||
|
|
||||||
activity.recreate();
|
|
||||||
} catch (Throwable err) {
|
} catch (Throwable err) {
|
||||||
Log.e("pushy", "Failed to restart application", err);
|
Log.e("pushy", "Failed to restart application", err);
|
||||||
}
|
}
|
||||||
|
110
docs/guide.md
110
docs/guide.md
@@ -6,31 +6,32 @@
|
|||||||
|
|
||||||
所以我们也假设你已经拥有了开发React Native应用的一切环境,包括`Node.js`、`npm`、`XCode`、`Android SDK`等等。
|
所以我们也假设你已经拥有了开发React Native应用的一切环境,包括`Node.js`、`npm`、`XCode`、`Android SDK`等等。
|
||||||
|
|
||||||
如果React Native的版本是0.45以下,并且你之前没安装过,你还必须安装[Android NDK](http://androiddevtools.cn),版本最好选用r10e,并设置环境变量`ANDROID_NDK_HOME`,指向你的NDK根目录(例如`/Users/tdzl2003/Downloads/android-ndk-r10e`)。0.46以上的React Native不需要安装NDK。
|
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
在你的项目根目录下运行以下命令:
|
在你的项目根目录下运行以下命令:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm i -g react-native-update-cli
|
npm i -g react-native-update-cli
|
||||||
npm i react-native-update@具体版本请看下面的表格
|
npm i react-native-update
|
||||||
react-native link react-native-update
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`npm install -g react-native-update-cli`这一句在每一台电脑上仅需运行一次。
|
> 如果下载极慢或者显示网络失败,请设置使用淘宝镜像`npx nrm use taobao`
|
||||||
|
|
||||||
* 注意 *
|
如果你的RN版本 >= 0.60,请在iOS目录下执行:
|
||||||
|
|
||||||
如果访问极慢或者显示网络失败,请设置使用淘宝镜像(也仅需设置一次):
|
|
||||||
```bash
|
```bash
|
||||||
npm install -g nrm
|
pod install
|
||||||
nrm use taobao
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 版本
|
如果你的RN版本 < 0.60,那么还需要[手动link](#一手动link)
|
||||||
|
|
||||||
因为React Native不同版本代码结构不同,因而请按下面表格对号入座:
|
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
如果你的RN版本比较老(< 0.46),请点击这里的注意事项
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
如果你的RN版本比较老,请按下面表格尝试老一些的版本(但这些版本我们已不再维护,不能保证可以使用):
|
||||||
|
|
||||||
| React Native版本 | react-native-update版本 |
|
| React Native版本 | react-native-update版本 |
|
||||||
| ---------------- | ----------------------- |
|
| ---------------- | ----------------------- |
|
||||||
@@ -38,29 +39,53 @@ nrm use taobao
|
|||||||
| 0.27 - 0.28 | 2.x |
|
| 0.27 - 0.28 | 2.x |
|
||||||
| 0.29 - 0.33 | 3.x |
|
| 0.29 - 0.33 | 3.x |
|
||||||
| 0.34 - 0.45 | 4.x |
|
| 0.34 - 0.45 | 4.x |
|
||||||
| 0.46及以上 | 5.x |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
安装命令示例:
|
安装命令示例:
|
||||||
```
|
```
|
||||||
npm i react-native-update@5.x
|
npm i react-native-update@4.x
|
||||||
```
|
```
|
||||||
|
|
||||||
|
如果RN的版本是0.45及以下,你还必须安装[Android NDK](http://androiddevtools.cn),版本最好选用r10e,并设置环境变量`ANDROID_NDK_HOME`,指向你的NDK根目录(例如`/Users/tdzl2003/Downloads/android-ndk-r10e`)。
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
请记得一定要重新编译(react-native run-ios或run-android命令编译,或在Xcode/Android Studio中重新编译)。
|
||||||
|
|
||||||
|
|
||||||
## 一、手动link
|
## 一、手动link
|
||||||
|
|
||||||
如果第一步的`react-native link`已成功(iOS工程和安卓工程均能看到依赖),可以跳过此步骤
|
如果RN版本 >= 0.60则可以跳过此步骤
|
||||||
|
|
||||||
### iOS
|
### iOS
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>RN < 0.60且使用CocoaPods(推荐)</summary>
|
||||||
|
|
||||||
|
1. 在ios/Podfile中添加
|
||||||
|
```
|
||||||
|
pod 'react-native-update', path: '../node_modules/react-native-update'
|
||||||
|
```
|
||||||
|
2. 在项目的ios目录下运行`pod install`
|
||||||
|
3. 重新编译
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>RN < 0.60且不使用CocoaPods</summary>
|
||||||
|
|
||||||
1. 在XCode中的Project Navigator里,右键点击`Libraries` ➜ `Add Files to [你的工程名]`
|
1. 在XCode中的Project Navigator里,右键点击`Libraries` ➜ `Add Files to [你的工程名]`
|
||||||
2. 进入`node_modules` ➜ `react-native-update` ➜ `ios 并选中 `RCTHotUpdate.xcodeproj`
|
2. 进入`node_modules` ➜ `react-native-update` ➜ `ios 并选中 `RCTHotUpdate.xcodeproj`
|
||||||
3. 在XCode中的project navigator里,选中你的工程,在 `Build Phases` ➜ `Link Binary With Libraries` 中添加 `libRCTHotUpdate.a`
|
3. 在XCode中的project navigator里,选中你的工程,在 `Build Phases` ➜ `Link Binary With Libraries` 中添加 `libRCTHotUpdate.a`
|
||||||
4. 继续在`Build Settings`里搜索`Header Search Path`,添加$(SRCROOT)/../node_modules/react-native-update/ios
|
4. 继续在`Build Settings`里搜索`Header Search Path`,添加$(SRCROOT)/../node_modules/react-native-update/ios
|
||||||
5. Run your project (`Cmd+R`)
|
5. 重新编译
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
### Android
|
### Android
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>RN < 0.60</summary>
|
||||||
1. 在`android/settings.gradle`中添加如下代码:
|
1. 在`android/settings.gradle`中添加如下代码:
|
||||||
```
|
```
|
||||||
include ':react-native-update'
|
include ':react-native-update'
|
||||||
@@ -69,43 +94,58 @@ npm i react-native-update@5.x
|
|||||||
|
|
||||||
2. 在`android/app/build.gradle`的 dependencies 部分增加如下代码:
|
2. 在`android/app/build.gradle`的 dependencies 部分增加如下代码:
|
||||||
```
|
```
|
||||||
compile project(':react-native-update')
|
implementation project(':react-native-update')
|
||||||
```
|
```
|
||||||
|
|
||||||
3. 检查你的RN版本,如果是0.29及以上, 打开`android/app/src/main/java/[...]/MainApplication.java`,否则打开`android/app/src/main/java/[...]/MainActivity.java`
|
3. 打开`android/app/src/main/java/[...]/MainApplication.java`,
|
||||||
- 在文件开头增加 `import cn.reactnative.modules.update.UpdatePackage;`
|
- 在文件开头增加 `import cn.reactnative.modules.update.UpdatePackage;`
|
||||||
- 在`getPackages()` 方法中增加 `new UpdatePackage()`(注意上一行可能要增加一个逗号)
|
- 在`getPackages()` 方法中增加 `new UpdatePackage()`(注意上一行可能要增加一个逗号)
|
||||||
|
</details>
|
||||||
|
|
||||||
## 二、配置Bundle URL
|
## 二、配置Bundle URL
|
||||||
|
|
||||||
|
注意此步骤无论任何版本,目前都需要手动配置。
|
||||||
|
|
||||||
### iOS
|
### iOS
|
||||||
|
|
||||||
首先在工程target的Build Phases->Link Binary with Libraries中加入`libz.tbd`、`libbz2.1.0.tbd`
|
1. (RN >= 0.60或者使用CocoaPods集成此步可跳过)在工程target的Build Phases->Link Binary with Libraries中加入`libz.tbd`、`libbz2.1.0.tbd`
|
||||||
|
|
||||||
|
2. 在你的AppDelegate.m文件中增加如下代码:
|
||||||
然后在你的AppDelegate.m文件中增加如下代码:
|
|
||||||
|
|
||||||
```objective-c
|
```objective-c
|
||||||
// ... 其它代码
|
// ... 其它代码
|
||||||
|
|
||||||
#import "RCTHotUpdate.h"
|
#import "RCTHotUpdate.h"
|
||||||
|
|
||||||
|
// 如果RN版本 >= 0.59,修改sourceURLForBridge
|
||||||
|
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
||||||
|
#else
|
||||||
|
// 非DEBUG情况下替换为热更新bundle
|
||||||
|
return [RCTHotUpdate bundleURL];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果RN版本 < 0.59,修改didFinishLaunchingWithOptions
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// 原来的jsCodeLocation保留在这里
|
// 原来的jsCodeLocation保留在这里
|
||||||
jsCodeLocation = ..........
|
jsCodeLocation = ..........
|
||||||
#else
|
#else
|
||||||
// 非DEBUG情况下启用热更新
|
// 非DEBUG情况下替换为热更新bundle
|
||||||
jsCodeLocation=[RCTHotUpdate bundleURL];
|
jsCodeLocation = [RCTHotUpdate bundleURL];
|
||||||
#endif
|
#endif
|
||||||
// ... 其它代码
|
// ... 其它代码
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Android
|
### Android
|
||||||
|
|
||||||
`0.29及以后版本`:在你的MainApplication中增加如下代码:
|
在MainApplication中增加如下代码:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
// ... 其它代码
|
// ... 其它代码
|
||||||
@@ -124,24 +164,6 @@ public class MainApplication extends Application implements ReactApplication {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`0.28及以前版本`:在你的MainActivity中增加如下代码:
|
|
||||||
|
|
||||||
```java
|
|
||||||
// ... 其它代码
|
|
||||||
|
|
||||||
// 请注意不要少了这句import
|
|
||||||
import cn.reactnative.modules.update.UpdateContext;
|
|
||||||
|
|
||||||
public class MainActivity extends ReactActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getJSBundleFile() {
|
|
||||||
return UpdateContext.getBundleUrl(this);
|
|
||||||
}
|
|
||||||
// ... 其它代码
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 三、登录与创建应用
|
## 三、登录与创建应用
|
||||||
|
|
||||||
首先请在<https://update.reactnative.cn>注册帐号,然后在你的项目根目录下运行以下命令:
|
首先请在<https://update.reactnative.cn>注册帐号,然后在你的项目根目录下运行以下命令:
|
||||||
@@ -170,7 +192,7 @@ App Name: <输入应用名字>
|
|||||||
```bash
|
```bash
|
||||||
$ pushy selectApp --platform ios
|
$ pushy selectApp --platform ios
|
||||||
1) 鱼多多(ios)
|
1) 鱼多多(ios)
|
||||||
3) 招财旺(ios)
|
2) 招财旺(ios)
|
||||||
|
|
||||||
Total 2 ios apps
|
Total 2 ios apps
|
||||||
Enter appId: <输入应用前面的编号>
|
Enter appId: <输入应用前面的编号>
|
||||||
|
37
index.d.ts
vendored
Normal file
37
index.d.ts
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
export const downloadRootDir: string;
|
||||||
|
export const packageVersion: string;
|
||||||
|
export const currentVersion: string;
|
||||||
|
export const isFirstTime: boolean;
|
||||||
|
export const isRolledBack: boolean;
|
||||||
|
|
||||||
|
export interface ExpiredResult {
|
||||||
|
expired: true;
|
||||||
|
downloadUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpTodateResult {
|
||||||
|
upToDate: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateAvailableResult {
|
||||||
|
update: true;
|
||||||
|
name: string; // version name
|
||||||
|
hash: string;
|
||||||
|
description: string;
|
||||||
|
metaInfo: string;
|
||||||
|
updateUrl: string;
|
||||||
|
pdiffUrl: string;
|
||||||
|
diffUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CheckResult = Partial<ExpiredResult & UpTodateResult & UpdateAvailableResult>;
|
||||||
|
|
||||||
|
export function checkUpdate(appkey: string): Promise<CheckResult>;
|
||||||
|
|
||||||
|
export function downloadUpdate(options: UpdateAvailableResult): Promise<undefined | string>;
|
||||||
|
|
||||||
|
export function switchVersion(hash: string): void;
|
||||||
|
|
||||||
|
export function switchVersionLater(hash: string): void;
|
||||||
|
|
||||||
|
export function markSuccess(): void;
|
@@ -59,6 +59,8 @@ typedef NS_ENUM(NSInteger, HotUpdateType) {
|
|||||||
HotUpdateTypePatchFromPpk = 3,
|
HotUpdateTypePatchFromPpk = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static BOOL ignoreRollback = false;
|
||||||
|
|
||||||
@implementation RCTHotUpdate {
|
@implementation RCTHotUpdate {
|
||||||
RCTHotUpdateManager *_fileManager;
|
RCTHotUpdateManager *_fileManager;
|
||||||
}
|
}
|
||||||
@@ -92,7 +94,7 @@ RCT_EXPORT_MODULE(RCTHotUpdate);
|
|||||||
BOOL isFirstLoadOK = [updateInfo[paramIsFirstLoadOk] boolValue];
|
BOOL isFirstLoadOK = [updateInfo[paramIsFirstLoadOk] boolValue];
|
||||||
|
|
||||||
NSString *loadVersioin = curVersion;
|
NSString *loadVersioin = curVersion;
|
||||||
BOOL needRollback = (isFirstTime == NO && isFirstLoadOK == NO) || loadVersioin.length<=0;
|
BOOL needRollback = (!ignoreRollback && isFirstTime == NO && isFirstLoadOK == NO) || loadVersioin.length<=0;
|
||||||
if (needRollback) {
|
if (needRollback) {
|
||||||
loadVersioin = lastVersion;
|
loadVersioin = lastVersion;
|
||||||
|
|
||||||
@@ -112,7 +114,10 @@ RCT_EXPORT_MODULE(RCTHotUpdate);
|
|||||||
[defaults synchronize];
|
[defaults synchronize];
|
||||||
// ...need clear files later
|
// ...need clear files later
|
||||||
}
|
}
|
||||||
else if (isFirstTime){
|
else if (isFirstTime && !ignoreRollback){
|
||||||
|
// bundleURL may be called many times, ignore rollbacks before process restarted again.
|
||||||
|
ignoreRollback = true;
|
||||||
|
|
||||||
NSMutableDictionary *newInfo = [[NSMutableDictionary alloc] initWithDictionary:updateInfo];
|
NSMutableDictionary *newInfo = [[NSMutableDictionary alloc] initWithDictionary:updateInfo];
|
||||||
newInfo[paramIsFirstTime] = @(NO);
|
newInfo[paramIsFirstTime] = @(NO);
|
||||||
[defaults setObject:newInfo forKey:keyUpdateInfo];
|
[defaults setObject:newInfo forKey:keyUpdateInfo];
|
||||||
|
@@ -2,15 +2,16 @@
|
|||||||
* Created by tdzl2003 on 2/22/16.
|
* Created by tdzl2003 on 2/22/16.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as path from 'path';
|
const path = require('path');
|
||||||
import { getRNVersion, translateOptions } from './utils';
|
import { getRNVersion, translateOptions } from './utils';
|
||||||
import * as fs from 'fs-extra';
|
import * as fs from 'fs-extra';
|
||||||
import { ZipFile } from 'yazl';
|
import { ZipFile } from 'yazl';
|
||||||
import { open as openZipFile } from 'yauzl';
|
import { open as openZipFile } from 'yauzl';
|
||||||
// import {diff} from 'node-bsdiff';
|
|
||||||
import { question } from './utils';
|
import { question } from './utils';
|
||||||
import { checkPlatform } from './app';
|
import { checkPlatform } from './app';
|
||||||
const { spawn } = require('child_process');
|
const { spawn, spawnSync, execSync } = require('child_process');
|
||||||
|
const g2js = require('gradle-to-js/lib/parser');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
var diff;
|
var diff;
|
||||||
try {
|
try {
|
||||||
@@ -19,12 +20,22 @@ try {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
diff = function() {
|
diff = function() {
|
||||||
console.warn(
|
console.warn(
|
||||||
'This function needs "node-bsdiff". Please run "npm i node-bsdiff -S" from your project directory first!',
|
'This function needs "node-bsdiff". Please run "npm i node-bsdiff" from your project directory first!',
|
||||||
);
|
);
|
||||||
throw new Error('This function needs module "node-bsdiff". Please install it first.');
|
throw new Error('This function needs module "node-bsdiff". Please install it first.');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function exec(command) {
|
||||||
|
const commandResult = spawnSync(command, {
|
||||||
|
shell: true,
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
if (commandResult.error) {
|
||||||
|
throw commandResult.error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function runReactNativeBundleCommand(
|
async function runReactNativeBundleCommand(
|
||||||
bundleName,
|
bundleName,
|
||||||
development,
|
development,
|
||||||
@@ -45,8 +56,8 @@ async function runReactNativeBundleCommand(
|
|||||||
fs.emptyDirSync(outputFolder);
|
fs.emptyDirSync(outputFolder);
|
||||||
|
|
||||||
Array.prototype.push.apply(reactNativeBundleArgs, [
|
Array.prototype.push.apply(reactNativeBundleArgs, [
|
||||||
path.join('node_modules', 'react-native', 'local-cli', 'cli.js'),
|
path.join("node_modules", "react-native", "local-cli", "cli.js"),
|
||||||
'bundle',
|
"bundle",
|
||||||
'--assets-dest',
|
'--assets-dest',
|
||||||
outputFolder,
|
outputFolder,
|
||||||
'--bundle-output',
|
'--bundle-output',
|
||||||
@@ -67,11 +78,10 @@ async function runReactNativeBundleCommand(
|
|||||||
reactNativeBundleArgs.push('--config', config);
|
reactNativeBundleArgs.push('--config', config);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Running "react-native bundle" command:\n`);
|
|
||||||
const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
|
const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
|
||||||
console.log(`node ${reactNativeBundleArgs.join(' ')}`);
|
console.log(`Running bundle command: node ${reactNativeBundleArgs.join(' ')}`);
|
||||||
|
|
||||||
return new Promise((resolve, reject, notify) => {
|
return new Promise((resolve, reject) => {
|
||||||
reactNativeBundleProcess.stdout.on('data', data => {
|
reactNativeBundleProcess.stdout.on('data', data => {
|
||||||
console.log(data.toString().trim());
|
console.log(data.toString().trim());
|
||||||
});
|
});
|
||||||
@@ -80,16 +90,48 @@ async function runReactNativeBundleCommand(
|
|||||||
console.error(data.toString().trim());
|
console.error(data.toString().trim());
|
||||||
});
|
});
|
||||||
|
|
||||||
reactNativeBundleProcess.on('close', exitCode => {
|
reactNativeBundleProcess.on('close', async exitCode => {
|
||||||
if (exitCode) {
|
if (exitCode) {
|
||||||
reject(new Error(`"react-native bundle" command exited with code ${exitCode}.`));
|
reject(new Error(`"react-native bundle" command exited with code ${exitCode}.`));
|
||||||
|
} else {
|
||||||
|
if (platform === 'android') {
|
||||||
|
await compileHermesByteCode(bundleName, outputFolder);
|
||||||
|
}
|
||||||
|
resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(null);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHermesOSBin() {
|
||||||
|
if (os.platform() === 'win32') return 'win64-bin';
|
||||||
|
if (os.platform() === 'darwin') return 'osx-bin';
|
||||||
|
if (os.platform() === 'linux') return 'linux64-bin';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function compileHermesByteCode(bundleName, outputFolder) {
|
||||||
|
let enableHermes = false;
|
||||||
|
try {
|
||||||
|
const gradleConfig = await g2js.parseFile('android/app/build.gradle');
|
||||||
|
const projectConfig = gradleConfig['project.ext.react'];
|
||||||
|
for (const packagerConfig of projectConfig) {
|
||||||
|
if (packagerConfig.includes('enableHermes') && packagerConfig.includes('true')) {
|
||||||
|
enableHermes = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
if (enableHermes) {
|
||||||
|
console.log(`Hermes enabled, now compiling to hermes bytecode:\n`);
|
||||||
|
const hermesPath = fs.existsSync('node_modules/hermes-engine')
|
||||||
|
? 'node_modules/hermes-engine'
|
||||||
|
: 'node_modules/hermesvm';
|
||||||
|
execSync(
|
||||||
|
`${hermesPath}/${getHermesOSBin()}/hermes -emit-binary -out ${outputFolder}/${bundleName} ${outputFolder}/${bundleName} -O`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function pack(dir, output) {
|
async function pack(dir, output) {
|
||||||
console.log('Packing');
|
console.log('Packing');
|
||||||
fs.ensureDirSync(path.dirname(output));
|
fs.ensureDirSync(path.dirname(output));
|
||||||
@@ -394,10 +436,9 @@ export const commands = {
|
|||||||
throw new Error('Platform must be specified.');
|
throw new Error('Platform must be specified.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// const { version, major, minor } = getRNVersion();
|
const { version, major, minor } = getRNVersion();
|
||||||
|
|
||||||
// console.log('Bundling with React Native version: ', version);
|
|
||||||
|
|
||||||
|
console.log('Bundling with React Native version: ', version);
|
||||||
|
|
||||||
await runReactNativeBundleCommand(bundleName, dev, entryFile, intermediaDir, platform);
|
await runReactNativeBundleCommand(bundleName, dev, entryFile, intermediaDir, platform);
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-update",
|
"name": "react-native-update",
|
||||||
"version": "5.1.9",
|
"version": "5.2.8",
|
||||||
"description": "react-native hot update",
|
"description": "react-native hot update",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
"decompress-zip": "^0.3.1",
|
"decompress-zip": "^0.3.1",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
"glob": "^7.1.2",
|
"glob": "^7.1.2",
|
||||||
|
"gradle-to-js": "^2.0.0",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"node-apk-parser": "^0.2.3",
|
"node-apk-parser": "^0.2.3",
|
||||||
"progress": "^1.1.8",
|
"progress": "^1.1.8",
|
||||||
|
32
react-native-update.podspec
Normal file
32
react-native-update.podspec
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
require 'json'
|
||||||
|
|
||||||
|
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
||||||
|
|
||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = package['name']
|
||||||
|
s.version = package['version']
|
||||||
|
s.summary = package['description']
|
||||||
|
s.license = package['license']
|
||||||
|
|
||||||
|
s.authors = package['author']
|
||||||
|
s.homepage = package['homepage']
|
||||||
|
|
||||||
|
s.platform = :ios, "7.0"
|
||||||
|
s.source = { :git => 'https://github.com/reactnativecn/react-native-pushy.git', :tag => '#{s.version}' }
|
||||||
|
s.libraries = 'bz2', 'z'
|
||||||
|
s.vendored_libraries = 'RCTHotUpdate/libRCTHotUpdate.a'
|
||||||
|
s.pod_target_xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '"$(SRCROOT)/../node_modules/react-native-update/ios"' }
|
||||||
|
|
||||||
|
s.dependency 'React'
|
||||||
|
s.dependency 'SSZipArchive'
|
||||||
|
|
||||||
|
s.subspec 'RCTHotUpdate' do |ss|
|
||||||
|
ss.source_files = 'ios/RCTHotUpdate/*.{h,m}'
|
||||||
|
ss.public_header_files = ['ios/RCTHotUpdate/RCTHotUpdate.h']
|
||||||
|
end
|
||||||
|
|
||||||
|
s.subspec 'BSDiff' do |ss|
|
||||||
|
ss.source_files = 'ios/RCTHotUpdate/BSDiff/**/*.{h,m,c}'
|
||||||
|
ss.private_header_files = 'ios/RCTHotUpdate/BSDiff/**/*.h'
|
||||||
|
end
|
||||||
|
end
|
12
yarn.lock
12
yarn.lock
@@ -1201,6 +1201,13 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
|||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "http://registry.npm.taobao.org/graceful-readlink/download/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
resolved "http://registry.npm.taobao.org/graceful-readlink/download/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
|
||||||
|
|
||||||
|
gradle-to-js@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.npm.taobao.org/gradle-to-js/download/gradle-to-js-2.0.0.tgz#b790a97376d3d713105a086590e569610f7e6bc4"
|
||||||
|
integrity sha1-t5Cpc3bT1xMQWghlkOVpYQ9+a8Q=
|
||||||
|
dependencies:
|
||||||
|
lodash.merge "4.6.2"
|
||||||
|
|
||||||
har-validator@~2.0.6:
|
har-validator@~2.0.6:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "http://registry.npm.taobao.org/har-validator/download/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
|
resolved "http://registry.npm.taobao.org/har-validator/download/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d"
|
||||||
@@ -1601,6 +1608,11 @@ lodash.keysin@^3.0.0:
|
|||||||
lodash.isarguments "^3.0.0"
|
lodash.isarguments "^3.0.0"
|
||||||
lodash.isarray "^3.0.0"
|
lodash.isarray "^3.0.0"
|
||||||
|
|
||||||
|
lodash.merge@4.6.2:
|
||||||
|
version "4.6.2"
|
||||||
|
resolved "https://registry.npm.taobao.org/lodash.merge/download/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||||
|
integrity sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo=
|
||||||
|
|
||||||
lodash.pick@^3.1.0:
|
lodash.pick@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "http://registry.npm.taobao.org/lodash.pick/download/lodash.pick-3.1.0.tgz#f252a855b2046b61bcd3904b26f76bd2efc65550"
|
resolved "http://registry.npm.taobao.org/lodash.pick/download/lodash.pick-3.1.0.tgz#f252a855b2046b61bcd3904b26f76bd2efc65550"
|
||||||
|
Reference in New Issue
Block a user