ReactNative 的远程调试原理

众所周知,RN 提供了一个远程调试的功能,在调试的过程中可以自动刷新资源,这极大地方便了开发的过程。但这个方便的功能是如何实现的呢?开发机是如何得知需要从哪里拉取资源的呢?这两天正在搞 RN 方面的研究,正好研究了一下这个问题,感觉这是一个很好的调试思路,以后可能会有用,先在这做个记录。

在 react-native-xcode.sh 脚本中使用下面的代码获取了作为 debug server 的电脑的 IP 地址
IP=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d\ -f2 | awk 'NR==1{print $1}')

然后使用如下语句将 IP 地址写入 ip.txt 文件中,然后将这个文件放到 app 的资源目录下

echo "$IP" > "$DEST/ip.txt"

然后使用 Xcode 构建 APP 的时候,这个 ip.txt 文件会作为资源被打包进 app 安装包中。当 ReactNative 程序开始运行的时候在 RCTBundleURLProviderguessPackagerHost 方法中读取这个文件以获取 IP 地址,然后从这个 IP 地址的 debug server 上获取 jsbundle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (NSString *)guessPackagerHost
{
static NSString *ipGuess;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSString *ipPath = [[NSBundle mainBundle] pathForResource:@"ip" ofType:@"txt"];
ipGuess = [[NSString stringWithContentsOfFile:ipPath encoding:NSUTF8StringEncoding error:nil]
stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
});

NSString *host = ipGuess ?: @"localhost";
if ([self isPackagerRunning:host]) {
return host;
}
return nil;
}