react-native-debug-toolkit 3.3.2 → 3.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,7 +77,46 @@ In the app, open Debug Panel -> `DevConnect` -> `Send Once` or `Start Live Sync`
77
77
 
78
78
  DevConnect auto-detects simulator/emulator and uses local host settings automatically. On real devices, enter your computer IP to connect.
79
79
 
80
- For Remote JS Bundle, run Metro on your computer, enter computer IP and Metro port in `DevConnect`, then tap `Use Metro Bundle`. DevConnect writes React Native's native dev-server host setting and reloads the app. The IP and ports are persisted through AsyncStorage when installed, or through the native module after rebuild.
80
+ ### Embedded Debug Bundle
81
+
82
+ Debug builds need an embedded JS bundle for cold start when Metro is off.
83
+
84
+ Bare React Native:
85
+
86
+ ```bash
87
+ npx debug-toolkit setup-bundle
88
+ git diff
89
+ git commit -am "chore: enable debug bundle embedding"
90
+ ```
91
+
92
+ Expo dev-client:
93
+
94
+ ```json
95
+ {
96
+ "expo": {
97
+ "plugins": [
98
+ ["react-native-debug-toolkit/dev-client", { "embedBundle": true }]
99
+ ]
100
+ }
101
+ }
102
+ ```
103
+
104
+ Verify built artifacts:
105
+
106
+ ```bash
107
+ npx debug-toolkit doctor-bundle --platform ios --app path/to/App.app
108
+ npx debug-toolkit doctor-bundle --platform android --apk path/to/app-debug.apk
109
+ ```
110
+
111
+ After setup, build machines run normal Xcode, Gradle, React Native, or EAS commands. Do not run a separate mutation command on every build.
112
+
113
+ For Remote JS Bundle, run Metro on your computer, enter computer IP and Metro port in `DevConnect`, then tap `Use Metro Bundle`. DevConnect persists the host and hot-reloads from Metro. Use **Reset** to go back to the embedded bundle.
114
+
115
+ > **Debug builds only.** Metro host switching works in Debug builds. Release builds load the embedded bundle and the controls are disabled (`release: disabled` badge).
116
+
117
+ **iOS — no AppDelegate changes required.** On install, DevConnect hooks `RCTBundleURLProvider` so the app **cold-starts from the embedded `main.jsbundle`** and only connects to Metro after you apply a host in the panel (fixes Expo `.expo/.virtual-metro-entry` red screens when Metro is off).
118
+
119
+ The IP and ports are persisted through AsyncStorage when installed, or through the native module after rebuild.
81
120
 
82
121
  QR scan is optional. Install `react-native-camera-kit` or `expo-camera` in the app to enable the scan button. The app must request camera permission before scanning.
83
122
 
package/README.zh-CN.md CHANGED
@@ -77,7 +77,46 @@ App 内打开 Debug Panel -> `DevConnect` -> `Send Once` 或 `Start Live Sync`
77
77
 
78
78
  DevConnect 自动识别模拟器/真机,模拟器下自动使用本机 Metro/daemon 地址。真机需输入电脑 IP 地址。
79
79
 
80
- Remote JS Bundle:先在电脑启动 Metro,在 `DevConnect` 输入电脑 IP 和 Metro 端口,然后点 `Use Metro Bundle`。DevConnect 会写入 React Native 原生 dev-server host 设置并 reload App。IP 和端口会通过 AsyncStorage 持久化;如果没装 AsyncStorage,则在重建后通过本库原生模块持久化。
80
+ ### Debug 包内置 Bundle
81
+
82
+ Debug 包要在 Metro 关闭时冷启动,必须内置 JS bundle。
83
+
84
+ Bare React Native:
85
+
86
+ ```bash
87
+ npx debug-toolkit setup-bundle
88
+ git diff
89
+ git commit -am "chore: enable debug bundle embedding"
90
+ ```
91
+
92
+ Expo dev-client:
93
+
94
+ ```json
95
+ {
96
+ "expo": {
97
+ "plugins": [
98
+ ["react-native-debug-toolkit/dev-client", { "embedBundle": true }]
99
+ ]
100
+ }
101
+ }
102
+ ```
103
+
104
+ 验证产物:
105
+
106
+ ```bash
107
+ npx debug-toolkit doctor-bundle --platform ios --app path/to/App.app
108
+ npx debug-toolkit doctor-bundle --platform android --apk path/to/app-debug.apk
109
+ ```
110
+
111
+ setup 后配置进仓库,打包机继续跑正常 Xcode、Gradle、React Native 或 EAS 命令。不要每次打包再跑额外修改命令。
112
+
113
+ Remote JS Bundle:先在电脑启动 Metro,在 `DevConnect` 输入电脑 IP 和 Metro 端口,然后点 `Use Metro Bundle`。DevConnect 会持久化 host 并从 Metro 热重载。点 **Reset** 可回到内置 bundle。
114
+
115
+ > **仅 Debug 包可用。** Release 包控件会显示 `release: disabled` 并禁用。
116
+
117
+ **iOS — 无需改 AppDelegate。** 安装本库后会 hook `RCTBundleURLProvider`:**未配置 IP 时冷启动走内置 `main.jsbundle`**,只有在面板里应用 host 后才连 Metro(可避免 Metro 未开时的 `.expo/.virtual-metro-entry` 红屏)。
118
+
119
+ IP 和端口会通过 AsyncStorage 持久化;如果没装 AsyncStorage,则在重建后通过本库原生模块持久化。
81
120
 
82
121
  扫码是可选能力。App 安装 `react-native-camera-kit` 或 `expo-camera` 后,DevConnect 才显示扫码按钮。App 仍需自己配置相机权限文案,并在使用扫码前申请相机权限。
83
122
 
package/app.plugin.js ADDED
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ function markTestConfig(config) {
4
+ config.extra = config.extra || {};
5
+ config.extra.reactNativeDebugToolkit = {
6
+ ...(config.extra.reactNativeDebugToolkit || {}),
7
+ embedBundle: true,
8
+ };
9
+ return config;
10
+ }
11
+
12
+ function loadConfigPlugins() {
13
+ try {
14
+ return require('@expo/config-plugins');
15
+ } catch {
16
+ throw new Error(
17
+ 'react-native-debug-toolkit/dev-client requires @expo/config-plugins during Expo prebuild.',
18
+ );
19
+ }
20
+ }
21
+
22
+ function withDebugToolkitDevClient(config, props = {}) {
23
+ if (!props.embedBundle) {
24
+ return config;
25
+ }
26
+
27
+ if (props._testOnly) {
28
+ return markTestConfig(config);
29
+ }
30
+
31
+ const { withDangerousMod } = loadConfigPlugins();
32
+ const { setupIosBundle } = require('./scripts/bundle/ios');
33
+ const { setupAndroidBundle } = require('./scripts/bundle/android');
34
+
35
+ config = withDangerousMod(config, ['ios', async (modConfig) => {
36
+ setupIosBundle({
37
+ cwd: modConfig.modRequest.projectRoot,
38
+ iosTarget: props.iosTarget,
39
+ });
40
+ return modConfig;
41
+ }]);
42
+
43
+ config = withDangerousMod(config, ['android', async (modConfig) => {
44
+ setupAndroidBundle({ cwd: modConfig.modRequest.projectRoot });
45
+ return modConfig;
46
+ }]);
47
+
48
+ return config;
49
+ }
50
+
51
+ module.exports = withDebugToolkitDevClient;
@@ -27,12 +27,19 @@ function hasHelpFlag(args) {
27
27
  function printHelp() {
28
28
  process.stderr.write(
29
29
  'Usage: debug-toolkit [--host 0.0.0.0] [--port 3799] [--token dev-token] [--store ~/.react-native-debug-toolkit/daemon-devices.json] [--daemon-only]\n'
30
+ + ' debug-toolkit setup-bundle [--platform ios|android] [--undo] [--check] [--ios-target <name>]\n'
31
+ + ' debug-toolkit doctor-bundle --platform ios --app <path-to.app>\n'
32
+ + ' debug-toolkit doctor-bundle --platform android --apk <path-to.apk>\n'
30
33
  + '\n'
31
34
  + 'Starts the debug toolkit: daemon (HTTP + Web Console) and MCP stdio server.\n'
32
35
  + '\n'
33
- + 'Options:\n'
36
+ + 'Commands:\n'
37
+ + ' setup-bundle Persistently configure host app debug builds to embed JS bundle\n'
38
+ + ' doctor-bundle Verify source config or built app package contains embedded bundle\n'
39
+ + '\n'
40
+ + 'Daemon options:\n'
34
41
  + ' --host <addr> Host to bind (default: 0.0.0.0)\n'
35
- + ' --port <port> Port to bind (default: 3799)\n'
42
+ + ' --port <port> Port to bind (default: 3799)\n'
36
43
  + ' --token <str> Auth token for daemon endpoints\n'
37
44
  + ' --store <path> Device log store path\n'
38
45
  + ' --daemon-only Start only the HTTP daemon and Web Console\n'
@@ -57,6 +64,15 @@ async function main() {
57
64
  return;
58
65
  }
59
66
 
67
+ if (['setup-bundle', 'doctor-bundle', 'embed'].includes(args[0])) {
68
+ const { runBundleCli } = require('../scripts/bundle/cli');
69
+ const code = await runBundleCli(args);
70
+ if (code !== 0) {
71
+ process.exitCode = code;
72
+ }
73
+ return;
74
+ }
75
+
60
76
  const host = readOption(args, '--host', process.env.DEBUG_TOOLKIT_DAEMON_HOST || DEFAULT_HOST);
61
77
  const port = Number(readOption(args, '--port', process.env.DEBUG_TOOLKIT_DAEMON_PORT || DEFAULT_PORT));
62
78
  const token = readOption(args, '--token', process.env.DEBUG_TOOLKIT_DAEMON_TOKEN || '');
package/dev-client.js ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('./app.plugin');
@@ -0,0 +1,17 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ NS_ASSUME_NONNULL_BEGIN
4
+
5
+ /**
6
+ Returns a Metro bundle URL when the user has applied a host via DevConnect; otherwise nil.
7
+
8
+ Zero-config: installing this pod hooks RCTBundleURLProvider so cold start uses the embedded
9
+ main.jsbundle until DevConnect applies a host. You do not need to change AppDelegate.
10
+
11
+ Optional override for custom bundleURL() implementations:
12
+
13
+ if let metro = DebugToolkitMetroBundleURL() { return metro }
14
+ */
15
+ FOUNDATION_EXPORT NSURL * _Nullable DebugToolkitMetroBundleURL(void);
16
+
17
+ NS_ASSUME_NONNULL_END