@rnx-kit/cli 0.16.13 → 0.16.15
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/CHANGELOG.md +21 -0
- package/coverage/clover.xml +2 -2
- package/coverage/lcov-report/index.html +1 -1
- package/coverage/lcov-report/src/bundle/defaultPlugins.ts.html +1 -1
- package/coverage/lcov-report/src/bundle/index.html +1 -1
- package/coverage/lcov-report/src/bundle/kit-config.ts.html +1 -1
- package/coverage/lcov-report/src/bundle/metro.ts.html +1 -1
- package/coverage/lcov-report/src/bundle/overrides.ts.html +1 -1
- package/coverage/lcov-report/src/copy-assets.ts.html +1 -1
- package/coverage/lcov-report/src/index.html +1 -1
- package/coverage/lcov-report/src/metro-config.ts.html +1 -1
- package/coverage/lcov-report/src/test.ts.html +1 -1
- package/lib/bundle.d.ts +1 -1
- package/lib/bundle.d.ts.map +1 -1
- package/lib/bundle.js.map +1 -1
- package/lib/clean.d.ts.map +1 -1
- package/lib/clean.js.map +1 -1
- package/lib/ram-bundle.d.ts +1 -1
- package/lib/ram-bundle.d.ts.map +1 -1
- package/lib/ram-bundle.js.map +1 -1
- package/lib/serve/external.d.ts +4 -0
- package/lib/serve/external.d.ts.map +1 -0
- package/lib/serve/external.js +29 -0
- package/lib/serve/external.js.map +1 -0
- package/lib/serve/help.d.ts +7 -0
- package/lib/serve/help.d.ts.map +1 -0
- package/lib/serve/help.js +50 -0
- package/lib/serve/help.js.map +1 -0
- package/lib/serve/keyboard.d.ts +11 -0
- package/lib/serve/keyboard.d.ts.map +1 -0
- package/lib/serve/keyboard.js +64 -0
- package/lib/serve/keyboard.js.map +1 -0
- package/lib/serve/types.d.ts +76 -0
- package/lib/serve/types.d.ts.map +1 -0
- package/lib/serve/types.js +3 -0
- package/lib/serve/types.js.map +1 -0
- package/lib/start.d.ts +3 -19
- package/lib/start.d.ts.map +1 -1
- package/lib/start.js +103 -156
- package/lib/start.js.map +1 -1
- package/lib/write-third-party-notices.d.ts +1 -1
- package/lib/write-third-party-notices.d.ts.map +1 -1
- package/lib/write-third-party-notices.js.map +1 -1
- package/package.json +17 -13
- package/src/bundle.ts +1 -1
- package/src/clean.ts +1 -3
- package/src/ram-bundle.ts +1 -1
- package/src/serve/external.ts +50 -0
- package/src/serve/help.ts +60 -0
- package/src/serve/keyboard.ts +76 -0
- package/src/serve/types.ts +86 -0
- package/src/start.ts +138 -222
- package/src/write-third-party-notices.ts +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { info } from "@rnx-kit/console";
|
|
2
|
+
import type { MetroTerminal } from "@rnx-kit/metro-service";
|
|
3
|
+
import nodeFetch from "node-fetch";
|
|
4
|
+
import qrcode from "qrcode";
|
|
5
|
+
import readline from "readline";
|
|
6
|
+
import type { DevServerMiddleware } from "./types";
|
|
7
|
+
|
|
8
|
+
type Options = {
|
|
9
|
+
devServerUrl: string;
|
|
10
|
+
help: () => void;
|
|
11
|
+
messageSocketEndpoint: DevServerMiddleware["messageSocketEndpoint"];
|
|
12
|
+
terminal: MetroTerminal["terminal"];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function attachKeyHandlers({
|
|
16
|
+
devServerUrl,
|
|
17
|
+
help,
|
|
18
|
+
messageSocketEndpoint,
|
|
19
|
+
terminal,
|
|
20
|
+
}: Options) {
|
|
21
|
+
process.stdin.setRawMode(true);
|
|
22
|
+
process.stdin.on("keypress", (_key, data) => {
|
|
23
|
+
const { ctrl, name } = data;
|
|
24
|
+
if (ctrl === true) {
|
|
25
|
+
switch (name) {
|
|
26
|
+
case "c":
|
|
27
|
+
info("Exiting...");
|
|
28
|
+
process.exit();
|
|
29
|
+
break;
|
|
30
|
+
case "z":
|
|
31
|
+
process.emit("SIGTSTP", "SIGTSTP");
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
switch (name) {
|
|
36
|
+
case "d":
|
|
37
|
+
info("Opening developer menu...");
|
|
38
|
+
messageSocketEndpoint.broadcast("devMenu", undefined);
|
|
39
|
+
break;
|
|
40
|
+
|
|
41
|
+
case "h":
|
|
42
|
+
help();
|
|
43
|
+
break;
|
|
44
|
+
|
|
45
|
+
case "j": {
|
|
46
|
+
info("Opening debugger...");
|
|
47
|
+
// TODO: Remove `node-fetch` when we drop support for Node 16
|
|
48
|
+
const ftch = "fetch" in globalThis ? fetch : nodeFetch;
|
|
49
|
+
ftch(devServerUrl + "/open-debugger", { method: "POST" });
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
case "q": {
|
|
54
|
+
const url = `${devServerUrl}/index.bundle`;
|
|
55
|
+
qrcode.toString(url, { type: "terminal" }, (_err, qr) => {
|
|
56
|
+
terminal.log("");
|
|
57
|
+
terminal.log(url + ":");
|
|
58
|
+
terminal.log(qr);
|
|
59
|
+
});
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
case "r":
|
|
64
|
+
info("Reloading app...");
|
|
65
|
+
messageSocketEndpoint.broadcast("reload", undefined);
|
|
66
|
+
break;
|
|
67
|
+
|
|
68
|
+
case "return":
|
|
69
|
+
terminal.log("");
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
readline.emitKeypressEvents(process.stdin);
|
|
76
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type * as logger from "@rnx-kit/console";
|
|
2
|
+
import type { Server as Middleware } from "connect";
|
|
3
|
+
import type { Server as HttpServer } from "http";
|
|
4
|
+
import type { Server as HttpsServer } from "https";
|
|
5
|
+
import type { RunServerOptions } from "metro";
|
|
6
|
+
|
|
7
|
+
// https://github.com/react-native-community/cli/blob/11.x/packages/cli-server-api/src/index.ts#L32
|
|
8
|
+
type MiddlewareOptions = {
|
|
9
|
+
host?: string;
|
|
10
|
+
watchFolders: readonly string[];
|
|
11
|
+
port: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type WebSocketServer = Required<RunServerOptions>["websocketEndpoints"][string];
|
|
15
|
+
|
|
16
|
+
export type DevServerMiddleware = {
|
|
17
|
+
websocketEndpoints: RunServerOptions["websocketEndpoints"];
|
|
18
|
+
debuggerProxyEndpoint: {
|
|
19
|
+
server: WebSocketServer;
|
|
20
|
+
isDebuggerConnected: () => boolean;
|
|
21
|
+
};
|
|
22
|
+
messageSocketEndpoint: {
|
|
23
|
+
server: WebSocketServer;
|
|
24
|
+
broadcast: (method: string, params?: Record<string, unknown>) => void;
|
|
25
|
+
};
|
|
26
|
+
eventsSocketEndpoint: {
|
|
27
|
+
server: WebSocketServer;
|
|
28
|
+
reportEvent: (event: unknown) => void;
|
|
29
|
+
};
|
|
30
|
+
middleware: Middleware;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type DevServerMiddleware6 = Pick<DevServerMiddleware, "middleware"> & {
|
|
34
|
+
attachToServer: (server: HttpServer | HttpsServer) => {
|
|
35
|
+
debuggerProxy: DevServerMiddleware["debuggerProxyEndpoint"];
|
|
36
|
+
eventsSocket: DevServerMiddleware["eventsSocketEndpoint"];
|
|
37
|
+
messageSocket: DevServerMiddleware["messageSocketEndpoint"];
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** `@react-native-community/cli-server-api` */
|
|
42
|
+
export type CliServerApi = {
|
|
43
|
+
createDevServerMiddleware: (
|
|
44
|
+
options: MiddlewareOptions
|
|
45
|
+
) => DevServerMiddleware | DevServerMiddleware6;
|
|
46
|
+
indexPageMiddleware: Middleware;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// https://github.com/facebook/react-native/blob/d208dc422c9239d126e0da674451c5898d57319d/packages/community-cli-plugin/src/commands/start/runServer.js#L32
|
|
50
|
+
export type StartCommandArgs = {
|
|
51
|
+
assetPlugins?: string[];
|
|
52
|
+
cert?: string;
|
|
53
|
+
customLogReporterPath?: string;
|
|
54
|
+
host?: string;
|
|
55
|
+
https?: boolean;
|
|
56
|
+
maxWorkers?: number;
|
|
57
|
+
key?: string;
|
|
58
|
+
platforms?: string[];
|
|
59
|
+
port?: number;
|
|
60
|
+
resetCache?: boolean;
|
|
61
|
+
sourceExts?: string[];
|
|
62
|
+
transformer?: string;
|
|
63
|
+
watchFolders?: string[];
|
|
64
|
+
config?: string;
|
|
65
|
+
projectRoot?: string;
|
|
66
|
+
interactive: boolean;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// https://github.com/facebook/react-native/blob/3e7a873f2d1c5170a7f4c88064897e74a149c5d5/packages/dev-middleware/src/createDevMiddleware.js#L40
|
|
70
|
+
type DevMiddlewareAPI = {
|
|
71
|
+
middleware: Middleware;
|
|
72
|
+
websocketEndpoints: RunServerOptions["websocketEndpoints"];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type DevMiddlewareOptions = {
|
|
76
|
+
projectRoot: string;
|
|
77
|
+
logger?: typeof logger;
|
|
78
|
+
unstable_browserLauncher?: unknown;
|
|
79
|
+
unstable_eventReporter?: unknown;
|
|
80
|
+
unstable_experiments?: unknown;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** `@react-native/dev-middleware` */
|
|
84
|
+
export type CoreDevMiddleware = {
|
|
85
|
+
createDevMiddleware: (options: DevMiddlewareOptions) => DevMiddlewareAPI;
|
|
86
|
+
};
|
package/src/start.ts
CHANGED
|
@@ -1,67 +1,25 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import
|
|
3
|
-
import type { MetroTerminal } from "@rnx-kit/metro-service";
|
|
1
|
+
import type { Config } from "@react-native-community/cli-types";
|
|
2
|
+
import * as logger from "@rnx-kit/console";
|
|
4
3
|
import {
|
|
5
4
|
createTerminal,
|
|
5
|
+
isDevServerRunning,
|
|
6
6
|
loadMetroConfig,
|
|
7
7
|
startServer,
|
|
8
8
|
} from "@rnx-kit/metro-service";
|
|
9
|
-
import chalk from "chalk";
|
|
10
|
-
import type { Server as HttpServer } from "http";
|
|
11
|
-
import type { Server as HttpsServer } from "https";
|
|
12
9
|
import type { ReportableEvent, Reporter, RunServerOptions } from "metro";
|
|
13
10
|
import type { Middleware } from "metro-config";
|
|
14
11
|
import type Server from "metro/src/Server";
|
|
15
|
-
import * as os from "os";
|
|
16
12
|
import * as path from "path";
|
|
17
|
-
import qrcode from "qrcode";
|
|
18
|
-
import readline from "readline";
|
|
19
13
|
import { customizeMetroConfig } from "./metro-config";
|
|
14
|
+
import { requireExternal } from "./serve/external";
|
|
15
|
+
import { makeHelp } from "./serve/help";
|
|
16
|
+
import { attachKeyHandlers } from "./serve/keyboard";
|
|
20
17
|
import { getKitServerConfig } from "./serve/kit-config";
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
type DevServerMiddleware6 = Pick<DevServerMiddleware, "middleware"> & {
|
|
27
|
-
attachToServer: (server: HttpServer | HttpsServer) => {
|
|
28
|
-
debuggerProxy: DevServerMiddleware["debuggerProxyEndpoint"];
|
|
29
|
-
eventsSocket: DevServerMiddleware["eventsSocketEndpoint"];
|
|
30
|
-
messageSocket: DevServerMiddleware["messageSocketEndpoint"];
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export type CLIStartOptions = {
|
|
35
|
-
port: number;
|
|
36
|
-
host: string;
|
|
37
|
-
projectRoot?: string;
|
|
38
|
-
watchFolders?: string[];
|
|
39
|
-
assetPlugins?: string[];
|
|
40
|
-
sourceExts?: string[];
|
|
41
|
-
maxWorkers?: number;
|
|
42
|
-
resetCache?: boolean;
|
|
43
|
-
customLogReporterPath?: string;
|
|
44
|
-
https?: boolean;
|
|
45
|
-
key?: string;
|
|
46
|
-
cert?: string;
|
|
47
|
-
config?: string;
|
|
48
|
-
interactive: boolean;
|
|
49
|
-
id?: string;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
function friendlyRequire<T>(...modules: string[]): T {
|
|
53
|
-
try {
|
|
54
|
-
const modulePath = modules.reduce((startDir, module) => {
|
|
55
|
-
return require.resolve(module, { paths: [startDir] });
|
|
56
|
-
}, process.cwd());
|
|
57
|
-
return require(modulePath) as T;
|
|
58
|
-
} catch (_) {
|
|
59
|
-
const module = modules[modules.length - 1];
|
|
60
|
-
throw new Error(
|
|
61
|
-
`Cannot find module '${module}'. This probably means that '@rnx-kit/cli' is not compatible with the version of '@react-native-community/cli' that you are currently using. Please update to the latest version and try again. If the issue still persists after the update, please file a bug at https://github.com/microsoft/rnx-kit/issues.`
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
18
|
+
import type {
|
|
19
|
+
DevServerMiddleware,
|
|
20
|
+
DevServerMiddleware6,
|
|
21
|
+
StartCommandArgs,
|
|
22
|
+
} from "./serve/types";
|
|
65
23
|
|
|
66
24
|
function hasAttachToServerFunction(
|
|
67
25
|
devServer: DevServerMiddleware | DevServerMiddleware6
|
|
@@ -69,111 +27,32 @@ function hasAttachToServerFunction(
|
|
|
69
27
|
return "attachToServer" in devServer;
|
|
70
28
|
}
|
|
71
29
|
|
|
72
|
-
function makeHelp(terminal: MetroTerminal["terminal"]): () => void {
|
|
73
|
-
const menuItems: ("" | [string, string])[] = [
|
|
74
|
-
["R", "Reload the app"],
|
|
75
|
-
["D", "Open developer menu"],
|
|
76
|
-
["A", "Show bundler address QR code"],
|
|
77
|
-
"",
|
|
78
|
-
["H", "Show this help message"],
|
|
79
|
-
["Ctrl-C", "Quit"],
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
const margin = 4;
|
|
83
|
-
const maxColumnWidth = (index: number) => {
|
|
84
|
-
return (max: number, item: (typeof menuItems)[number]) => {
|
|
85
|
-
if (!item) {
|
|
86
|
-
return max;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const width = item[index].length;
|
|
90
|
-
return width > max ? width : max;
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const keyWidth = menuItems.reduce(maxColumnWidth(0), 0);
|
|
95
|
-
const labelWidth = menuItems.reduce(maxColumnWidth(1), 0);
|
|
96
|
-
const separator = `┠${"─".repeat(labelWidth + keyWidth + margin + 1)}`;
|
|
97
|
-
|
|
98
|
-
const dim = chalk.dim;
|
|
99
|
-
const lines = menuItems.map((item) => {
|
|
100
|
-
if (!item) {
|
|
101
|
-
return separator;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const [key, label] = item;
|
|
105
|
-
const labelPadding = labelWidth - label.length;
|
|
106
|
-
const keyPadding = keyWidth - key.length;
|
|
107
|
-
const padding = " ".repeat(labelPadding + keyPadding + margin);
|
|
108
|
-
return `┃ ${dim(label)}${padding}${key}`;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return () => {
|
|
112
|
-
for (const line of lines) {
|
|
113
|
-
terminal.log(line);
|
|
114
|
-
}
|
|
115
|
-
terminal.log("");
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
30
|
export async function rnxStart(
|
|
120
|
-
_argv:
|
|
121
|
-
|
|
122
|
-
|
|
31
|
+
_argv: string[],
|
|
32
|
+
ctx: Config,
|
|
33
|
+
args: StartCommandArgs
|
|
123
34
|
): Promise<void> {
|
|
124
|
-
const serverConfig = getKitServerConfig(
|
|
35
|
+
const serverConfig = getKitServerConfig(args);
|
|
125
36
|
|
|
126
|
-
const { createDevServerMiddleware, indexPageMiddleware } =
|
|
127
|
-
typeof CliServerApi
|
|
128
|
-
>(
|
|
129
|
-
"react-native",
|
|
130
|
-
"@react-native-community/cli",
|
|
37
|
+
const { createDevServerMiddleware, indexPageMiddleware } = requireExternal(
|
|
131
38
|
"@react-native-community/cli-server-api"
|
|
132
39
|
);
|
|
133
40
|
|
|
134
41
|
// interactive mode requires raw access to stdin
|
|
135
|
-
let interactive =
|
|
42
|
+
let interactive = args.interactive;
|
|
136
43
|
if (interactive) {
|
|
137
44
|
interactive = process.stdin.isTTY;
|
|
138
45
|
if (!interactive) {
|
|
139
|
-
|
|
140
|
-
chalk.yellow(
|
|
141
|
-
"Warning: Interactive mode is not supported on this terminal"
|
|
142
|
-
)
|
|
143
|
-
);
|
|
46
|
+
logger.warn("Interactive mode is not supported in this environment");
|
|
144
47
|
}
|
|
145
48
|
}
|
|
146
49
|
|
|
147
|
-
// create a Metro terminal and reporter for writing to the console
|
|
148
|
-
const { terminal, reporter: terminalReporter } = createTerminal(
|
|
149
|
-
cliOptions.customLogReporterPath
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
const printHelp = makeHelp(terminal);
|
|
153
|
-
|
|
154
|
-
// create a reporter function, to be bound to the Metro configuration.
|
|
155
|
-
// which writes to the Metro terminal and
|
|
156
|
-
// also notifies the `reportEvent` delegate.
|
|
157
|
-
let reportEventDelegate: Reporter["update"] | undefined = undefined;
|
|
158
|
-
const reporter: Reporter = {
|
|
159
|
-
update(event: ReportableEvent) {
|
|
160
|
-
terminalReporter.update(event);
|
|
161
|
-
if (reportEventDelegate) {
|
|
162
|
-
reportEventDelegate(event);
|
|
163
|
-
}
|
|
164
|
-
if (interactive && event.type === "dep_graph_loading") {
|
|
165
|
-
printHelp();
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
|
|
170
50
|
// load Metro configuration, applying overrides from the command line
|
|
171
|
-
const metroConfig = await loadMetroConfig(
|
|
172
|
-
...
|
|
51
|
+
const metroConfig = await loadMetroConfig(ctx, {
|
|
52
|
+
...args,
|
|
173
53
|
...(serverConfig.projectRoot
|
|
174
54
|
? { projectRoot: path.resolve(serverConfig.projectRoot) }
|
|
175
55
|
: undefined),
|
|
176
|
-
reporter,
|
|
177
56
|
...(serverConfig.sourceExts
|
|
178
57
|
? { sourceExts: serverConfig.sourceExts }
|
|
179
58
|
: undefined),
|
|
@@ -186,39 +65,89 @@ export async function rnxStart(
|
|
|
186
65
|
: undefined),
|
|
187
66
|
});
|
|
188
67
|
|
|
68
|
+
// create a Metro terminal and reporter for writing to the console
|
|
69
|
+
const { terminal, reporter: terminalReporter } = createTerminal(
|
|
70
|
+
args.customLogReporterPath
|
|
71
|
+
);
|
|
72
|
+
|
|
189
73
|
// customize the metro config to include plugins, presets, etc.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
74
|
+
const log = (message: string): void => terminal.log(message);
|
|
75
|
+
customizeMetroConfig(metroConfig, serverConfig, log);
|
|
76
|
+
|
|
77
|
+
const {
|
|
78
|
+
projectRoot,
|
|
79
|
+
server: { port },
|
|
80
|
+
watchFolders,
|
|
81
|
+
} = metroConfig;
|
|
82
|
+
const scheme = args.https === true ? "https" : "http";
|
|
83
|
+
const serverStatus = await isDevServerRunning(
|
|
84
|
+
scheme,
|
|
85
|
+
args.host,
|
|
86
|
+
port,
|
|
87
|
+
projectRoot
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
switch (serverStatus) {
|
|
91
|
+
case "already_running":
|
|
92
|
+
logger.info(
|
|
93
|
+
`A dev server is already running for this project on port ${port}. ` +
|
|
94
|
+
"Exiting..."
|
|
95
|
+
);
|
|
96
|
+
return;
|
|
97
|
+
case "in_use":
|
|
98
|
+
logger.error(
|
|
99
|
+
`Another process is using port ${port}. Please terminate this ` +
|
|
100
|
+
"process and try again, or try another port with `--port`."
|
|
101
|
+
);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
193
104
|
|
|
194
105
|
// create middleware -- a collection of plugins which handle incoming
|
|
195
106
|
// http(s) requests, routing them to static pages or JS functions.
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
107
|
+
const host = args.host?.length ? args.host : "localhost";
|
|
108
|
+
const devServer = createDevServerMiddleware({ host, port, watchFolders });
|
|
109
|
+
|
|
110
|
+
const coreDevMiddleware = (() => {
|
|
111
|
+
try {
|
|
112
|
+
// https://github.com/facebook/react-native/blob/3e7a873f2d1c5170a7f4c88064897e74a149c5d5/packages/community-cli-plugin/src/commands/start/runServer.js#L115
|
|
113
|
+
const { createDevMiddleware } = requireExternal(
|
|
114
|
+
"@react-native/dev-middleware"
|
|
115
|
+
);
|
|
116
|
+
return createDevMiddleware({
|
|
117
|
+
projectRoot,
|
|
118
|
+
logger,
|
|
119
|
+
unstable_experiments: {
|
|
120
|
+
// NOTE: Only affects the /open-debugger endpoint
|
|
121
|
+
enableCustomDebuggerFrontend: true,
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
} catch (_) {
|
|
125
|
+
// Fallback to the behavior from before 0.73
|
|
126
|
+
const middleware = devServer.middleware;
|
|
127
|
+
middleware.use(indexPageMiddleware);
|
|
128
|
+
|
|
129
|
+
// merge the Metro config middleware with our middleware
|
|
130
|
+
const enhanceMiddleware = metroConfig.server.enhanceMiddleware;
|
|
131
|
+
// @ts-expect-error We want to override `enhanceMiddleware`
|
|
132
|
+
metroConfig.server.enhanceMiddleware = (
|
|
133
|
+
metroMiddleware: Middleware,
|
|
134
|
+
metroServer: Server
|
|
135
|
+
) => {
|
|
136
|
+
return middleware.use(
|
|
137
|
+
enhanceMiddleware
|
|
138
|
+
? enhanceMiddleware(metroMiddleware, metroServer)
|
|
139
|
+
: metroMiddleware
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
})();
|
|
217
145
|
|
|
218
146
|
// `createDevServerMiddleware` changed its return type in
|
|
219
147
|
// https://github.com/react-native-community/cli/pull/1560
|
|
220
148
|
let websocketEndpoints: RunServerOptions["websocketEndpoints"] = undefined;
|
|
221
149
|
let messageSocketEndpoint: DevServerMiddleware["messageSocketEndpoint"];
|
|
150
|
+
let reportEventDelegate: Reporter["update"] | undefined = undefined;
|
|
222
151
|
|
|
223
152
|
if (!hasAttachToServerFunction(devServer)) {
|
|
224
153
|
websocketEndpoints = devServer.websocketEndpoints;
|
|
@@ -228,15 +157,42 @@ export async function rnxStart(
|
|
|
228
157
|
reportEventDelegate = devServer.eventsSocketEndpoint.reportEvent;
|
|
229
158
|
}
|
|
230
159
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
160
|
+
const printHelp = makeHelp(terminal, {
|
|
161
|
+
hasDebugger: Boolean(coreDevMiddleware),
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// @ts-expect-error We want to override `reporter`
|
|
165
|
+
metroConfig.reporter = {
|
|
166
|
+
update(event: ReportableEvent) {
|
|
167
|
+
terminalReporter.update(event);
|
|
168
|
+
if (reportEventDelegate) {
|
|
169
|
+
reportEventDelegate(event);
|
|
170
|
+
}
|
|
171
|
+
if (interactive && event.type === "dep_graph_loading") {
|
|
172
|
+
printHelp();
|
|
173
|
+
}
|
|
174
|
+
},
|
|
238
175
|
};
|
|
239
|
-
|
|
176
|
+
|
|
177
|
+
const serverInstance = await startServer(metroConfig, {
|
|
178
|
+
host: args.host,
|
|
179
|
+
secure: args.https,
|
|
180
|
+
secureCert: args.cert,
|
|
181
|
+
secureKey: args.key,
|
|
182
|
+
...(coreDevMiddleware
|
|
183
|
+
? {
|
|
184
|
+
unstable_extraMiddleware: [
|
|
185
|
+
devServer.middleware,
|
|
186
|
+
indexPageMiddleware,
|
|
187
|
+
coreDevMiddleware.middleware,
|
|
188
|
+
],
|
|
189
|
+
websocketEndpoints: {
|
|
190
|
+
...websocketEndpoints,
|
|
191
|
+
...coreDevMiddleware.websocketEndpoints,
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
: { websocketEndpoints }),
|
|
195
|
+
});
|
|
240
196
|
|
|
241
197
|
if (hasAttachToServerFunction(devServer)) {
|
|
242
198
|
const { messageSocket, eventsSocket } =
|
|
@@ -245,6 +201,10 @@ export async function rnxStart(
|
|
|
245
201
|
|
|
246
202
|
// bind our `reportEvent` delegate to the Metro server
|
|
247
203
|
reportEventDelegate = eventsSocket.reportEvent;
|
|
204
|
+
} else {
|
|
205
|
+
// `messageSocketEndpoint` should already be set at this point. But this
|
|
206
|
+
// makes TypeScript happier.
|
|
207
|
+
messageSocketEndpoint = devServer.messageSocketEndpoint;
|
|
248
208
|
}
|
|
249
209
|
|
|
250
210
|
// In Node 8, the default keep-alive for an HTTP connection is 5 seconds. In
|
|
@@ -262,55 +222,11 @@ export async function rnxStart(
|
|
|
262
222
|
// in interactive mode, listen for keyboard events from stdin and bind
|
|
263
223
|
// them to specific actions.
|
|
264
224
|
if (interactive) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (ctrl === true) {
|
|
271
|
-
switch (name) {
|
|
272
|
-
case "c":
|
|
273
|
-
terminal.log(chalk.green("Exiting..."));
|
|
274
|
-
process.exit();
|
|
275
|
-
break;
|
|
276
|
-
case "z":
|
|
277
|
-
process.emit("SIGTSTP", "SIGTSTP");
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
} else {
|
|
281
|
-
switch (name) {
|
|
282
|
-
case "a": {
|
|
283
|
-
const protocol = cliOptions.https ? "https" : "http";
|
|
284
|
-
const host = cliOptions.host || os.hostname();
|
|
285
|
-
const port = metroConfig.server.port;
|
|
286
|
-
const url = `${protocol}://${host}:${port}/index.bundle`;
|
|
287
|
-
qrcode.toString(url, { type: "terminal" }, (_err, qr) => {
|
|
288
|
-
terminal.log("");
|
|
289
|
-
terminal.log(url + ":");
|
|
290
|
-
terminal.log(qr);
|
|
291
|
-
});
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
case "d":
|
|
296
|
-
terminal.log(chalk.green("Opening developer menu..."));
|
|
297
|
-
messageSocketEndpoint.broadcast("devMenu", undefined);
|
|
298
|
-
break;
|
|
299
|
-
|
|
300
|
-
case "h":
|
|
301
|
-
printHelp();
|
|
302
|
-
break;
|
|
303
|
-
|
|
304
|
-
case "r":
|
|
305
|
-
terminal.log(chalk.green("Reloading app..."));
|
|
306
|
-
messageSocketEndpoint.broadcast("reload", undefined);
|
|
307
|
-
break;
|
|
308
|
-
|
|
309
|
-
case "return":
|
|
310
|
-
terminal.log("");
|
|
311
|
-
break;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
225
|
+
attachKeyHandlers({
|
|
226
|
+
devServerUrl: `${scheme}://${host}:${port}`,
|
|
227
|
+
help: printHelp,
|
|
228
|
+
messageSocketEndpoint,
|
|
229
|
+
terminal,
|
|
314
230
|
});
|
|
315
231
|
}
|
|
316
232
|
}
|