@react-native/community-cli-plugin 0.73.0-nightly-20230922-52104c6ee
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 +91 -0
- package/dist/commands/bundle/assetCatalogIOS.js +74 -0
- package/dist/commands/bundle/assetCatalogIOS.js.flow +29 -0
- package/dist/commands/bundle/assetPathUtils.js +79 -0
- package/dist/commands/bundle/assetPathUtils.js.flow +39 -0
- package/dist/commands/bundle/buildBundle.js +121 -0
- package/dist/commands/bundle/buildBundle.js.flow +64 -0
- package/dist/commands/bundle/filterPlatformAssetScales.js +47 -0
- package/dist/commands/bundle/filterPlatformAssetScales.js.flow +17 -0
- package/dist/commands/bundle/getAssetDestPathAndroid.js +32 -0
- package/dist/commands/bundle/getAssetDestPathAndroid.js.flow +19 -0
- package/dist/commands/bundle/getAssetDestPathIOS.js +34 -0
- package/dist/commands/bundle/getAssetDestPathIOS.js.flow +19 -0
- package/dist/commands/bundle/index.js +124 -0
- package/dist/commands/bundle/index.js.flow +18 -0
- package/dist/commands/bundle/saveAssets.js +138 -0
- package/dist/commands/bundle/saveAssets.js.flow +21 -0
- package/dist/commands/ram-bundle/index.js +45 -0
- package/dist/commands/ram-bundle/index.js.flow +15 -0
- package/dist/commands/start/attachKeyHandlers.js +109 -0
- package/dist/commands/start/attachKeyHandlers.js.flow +22 -0
- package/dist/commands/start/index.js +105 -0
- package/dist/commands/start/index.js.flow +18 -0
- package/dist/commands/start/runServer.js +173 -0
- package/dist/commands/start/runServer.js.flow +38 -0
- package/dist/index.flow.js +36 -0
- package/dist/index.flow.js.flow +16 -0
- package/dist/index.js +3 -0
- package/dist/index.js.flow +12 -0
- package/dist/utils/KeyPressHandler.js +91 -0
- package/dist/utils/KeyPressHandler.js.flow +22 -0
- package/dist/utils/isDevServerRunning.js +74 -0
- package/dist/utils/isDevServerRunning.js.flow +27 -0
- package/dist/utils/loadMetroConfig.js +107 -0
- package/dist/utils/loadMetroConfig.js.flow +33 -0
- package/dist/utils/metroPlatformResolver.js +46 -0
- package/dist/utils/metroPlatformResolver.js.flow +30 -0
- package/package.json +43 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
8
|
+
var _metro = _interopRequireDefault(require("metro"));
|
|
9
|
+
var _metroCore = require("metro-core");
|
|
10
|
+
var _path = _interopRequireDefault(require("path"));
|
|
11
|
+
var _devMiddleware = require("@react-native/dev-middleware");
|
|
12
|
+
var _cliServerApi = require("@react-native-community/cli-server-api");
|
|
13
|
+
var _cliTools = require("@react-native-community/cli-tools");
|
|
14
|
+
var _isDevServerRunning = _interopRequireDefault(
|
|
15
|
+
require("../../utils/isDevServerRunning")
|
|
16
|
+
);
|
|
17
|
+
var _loadMetroConfig = _interopRequireDefault(
|
|
18
|
+
require("../../utils/loadMetroConfig")
|
|
19
|
+
);
|
|
20
|
+
var _attachKeyHandlers = _interopRequireDefault(require("./attachKeyHandlers"));
|
|
21
|
+
function _interopRequireDefault(obj) {
|
|
22
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
26
|
+
*
|
|
27
|
+
* This source code is licensed under the MIT license found in the
|
|
28
|
+
* LICENSE file in the root directory of this source tree.
|
|
29
|
+
*
|
|
30
|
+
*
|
|
31
|
+
* @format
|
|
32
|
+
* @oncall react_native
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
async function runServer(_argv, ctx, args) {
|
|
36
|
+
const metroConfig = await (0, _loadMetroConfig.default)(ctx, {
|
|
37
|
+
config: args.config,
|
|
38
|
+
maxWorkers: args.maxWorkers,
|
|
39
|
+
port: args.port ?? 8081,
|
|
40
|
+
resetCache: args.resetCache,
|
|
41
|
+
watchFolders: args.watchFolders,
|
|
42
|
+
projectRoot: args.projectRoot,
|
|
43
|
+
sourceExts: args.sourceExts,
|
|
44
|
+
});
|
|
45
|
+
const host = args.host?.length ? args.host : "localhost";
|
|
46
|
+
const {
|
|
47
|
+
projectRoot,
|
|
48
|
+
server: { port },
|
|
49
|
+
watchFolders,
|
|
50
|
+
} = metroConfig;
|
|
51
|
+
const scheme = args.https === true ? "https" : "http";
|
|
52
|
+
const devServerUrl = `${scheme}://${host}:${port}`;
|
|
53
|
+
_cliTools.logger.info(`Welcome to React Native v${ctx.reactNativeVersion}`);
|
|
54
|
+
const serverStatus = await (0, _isDevServerRunning.default)(
|
|
55
|
+
scheme,
|
|
56
|
+
host,
|
|
57
|
+
port,
|
|
58
|
+
projectRoot
|
|
59
|
+
);
|
|
60
|
+
if (serverStatus === "matched_server_running") {
|
|
61
|
+
_cliTools.logger.info(
|
|
62
|
+
`A dev server is already running for this project on port ${port}. Exiting.`
|
|
63
|
+
);
|
|
64
|
+
return;
|
|
65
|
+
} else if (serverStatus === "port_taken") {
|
|
66
|
+
_cliTools.logger.error(
|
|
67
|
+
`Another process is running on port ${port}. Please terminate this ` +
|
|
68
|
+
'process and try again, or use another port with "--port".'
|
|
69
|
+
);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
_cliTools.logger.info(
|
|
73
|
+
`Starting dev server on port ${_chalk.default.bold(String(port))}...`
|
|
74
|
+
);
|
|
75
|
+
if (args.assetPlugins) {
|
|
76
|
+
// $FlowIgnore[cannot-write] Assigning to readonly property
|
|
77
|
+
metroConfig.transformer.assetPlugins = args.assetPlugins.map((plugin) =>
|
|
78
|
+
require.resolve(plugin)
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const {
|
|
82
|
+
middleware: communityMiddleware,
|
|
83
|
+
websocketEndpoints: communityWebsocketEndpoints,
|
|
84
|
+
messageSocketEndpoint,
|
|
85
|
+
eventsSocketEndpoint,
|
|
86
|
+
} = (0, _cliServerApi.createDevServerMiddleware)({
|
|
87
|
+
host,
|
|
88
|
+
port,
|
|
89
|
+
watchFolders,
|
|
90
|
+
});
|
|
91
|
+
const { middleware, websocketEndpoints } = (0,
|
|
92
|
+
_devMiddleware.createDevMiddleware)({
|
|
93
|
+
projectRoot,
|
|
94
|
+
serverBaseUrl: devServerUrl,
|
|
95
|
+
logger: _cliTools.logger,
|
|
96
|
+
unstable_experiments: {
|
|
97
|
+
// NOTE: Only affects the /open-debugger endpoint
|
|
98
|
+
enableCustomDebuggerFrontend: true,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
let reportEvent;
|
|
102
|
+
const terminal = new _metroCore.Terminal(process.stdout);
|
|
103
|
+
const ReporterImpl = getReporterImpl(args.customLogReporterPath);
|
|
104
|
+
const terminalReporter = new ReporterImpl(terminal);
|
|
105
|
+
// $FlowIgnore[cannot-write] Assigning to readonly property
|
|
106
|
+
metroConfig.reporter = {
|
|
107
|
+
update(event) {
|
|
108
|
+
terminalReporter.update(event);
|
|
109
|
+
if (reportEvent) {
|
|
110
|
+
reportEvent(event);
|
|
111
|
+
}
|
|
112
|
+
if (args.interactive && event.type === "initialize_done") {
|
|
113
|
+
_cliTools.logger.info("Dev server ready");
|
|
114
|
+
(0, _attachKeyHandlers.default)({
|
|
115
|
+
cliConfig: ctx,
|
|
116
|
+
devServerUrl,
|
|
117
|
+
serverInstance,
|
|
118
|
+
messageSocket: messageSocketEndpoint,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
const serverInstance = await _metro.default.runServer(metroConfig, {
|
|
124
|
+
host: args.host,
|
|
125
|
+
secure: args.https,
|
|
126
|
+
secureCert: args.cert,
|
|
127
|
+
secureKey: args.key,
|
|
128
|
+
unstable_extraMiddleware: [
|
|
129
|
+
communityMiddleware,
|
|
130
|
+
_cliServerApi.indexPageMiddleware,
|
|
131
|
+
middleware,
|
|
132
|
+
],
|
|
133
|
+
websocketEndpoints: {
|
|
134
|
+
...communityWebsocketEndpoints,
|
|
135
|
+
...websocketEndpoints,
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
reportEvent = eventsSocketEndpoint.reportEvent;
|
|
139
|
+
|
|
140
|
+
// In Node 8, the default keep-alive for an HTTP connection is 5 seconds. In
|
|
141
|
+
// early versions of Node 8, this was implemented in a buggy way which caused
|
|
142
|
+
// some HTTP responses (like those containing large JS bundles) to be
|
|
143
|
+
// terminated early.
|
|
144
|
+
//
|
|
145
|
+
// As a workaround, arbitrarily increase the keep-alive from 5 to 30 seconds,
|
|
146
|
+
// which should be enough to send even the largest of JS bundles.
|
|
147
|
+
//
|
|
148
|
+
// For more info: https://github.com/nodejs/node/issues/13391
|
|
149
|
+
//
|
|
150
|
+
serverInstance.keepAliveTimeout = 30000;
|
|
151
|
+
await _cliTools.version.logIfUpdateAvailable(ctx.root);
|
|
152
|
+
}
|
|
153
|
+
function getReporterImpl(customLogReporterPath) {
|
|
154
|
+
if (customLogReporterPath == null) {
|
|
155
|
+
return require("metro/src/lib/TerminalReporter");
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
// First we let require resolve it, so we can require packages in node_modules
|
|
159
|
+
// as expected. eg: require('my-package/reporter');
|
|
160
|
+
// $FlowIgnore[unsupported-syntax]
|
|
161
|
+
return require(customLogReporterPath);
|
|
162
|
+
} catch (e) {
|
|
163
|
+
if (e.code !== "MODULE_NOT_FOUND") {
|
|
164
|
+
throw e;
|
|
165
|
+
}
|
|
166
|
+
// If that doesn't work, then we next try relative to the cwd, eg:
|
|
167
|
+
// require('./reporter');
|
|
168
|
+
// $FlowIgnore[unsupported-syntax]
|
|
169
|
+
return require(_path.default.resolve(customLogReporterPath));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
var _default = runServer;
|
|
173
|
+
exports.default = _default;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Config } from "@react-native-community/cli-types";
|
|
13
|
+
export type StartCommandArgs = {
|
|
14
|
+
assetPlugins?: string[],
|
|
15
|
+
cert?: string,
|
|
16
|
+
customLogReporterPath?: string,
|
|
17
|
+
host?: string,
|
|
18
|
+
https?: boolean,
|
|
19
|
+
maxWorkers?: number,
|
|
20
|
+
key?: string,
|
|
21
|
+
platforms?: string[],
|
|
22
|
+
port?: number,
|
|
23
|
+
resetCache?: boolean,
|
|
24
|
+
sourceExts?: string[],
|
|
25
|
+
transformer?: string,
|
|
26
|
+
watchFolders?: string[],
|
|
27
|
+
config?: string,
|
|
28
|
+
projectRoot?: string,
|
|
29
|
+
interactive: boolean,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
declare function runServer(
|
|
33
|
+
_argv: Array<string>,
|
|
34
|
+
ctx: Config,
|
|
35
|
+
args: StartCommandArgs
|
|
36
|
+
): void;
|
|
37
|
+
|
|
38
|
+
declare export default runServer;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "bundleCommand", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _bundle.default;
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "ramBundleCommand", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _ramBundle.default;
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "startCommand", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _start.default;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "unstable_buildBundleWithConfig", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _buildBundle.unstable_buildBundleWithConfig;
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
var _bundle = _interopRequireDefault(require("./commands/bundle"));
|
|
31
|
+
var _ramBundle = _interopRequireDefault(require("./commands/ram-bundle"));
|
|
32
|
+
var _start = _interopRequireDefault(require("./commands/start"));
|
|
33
|
+
var _buildBundle = require("./commands/bundle/buildBundle");
|
|
34
|
+
function _interopRequireDefault(obj) {
|
|
35
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
36
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export { default as bundleCommand } from "./commands/bundle";
|
|
13
|
+
export { default as ramBundleCommand } from "./commands/ram-bundle";
|
|
14
|
+
export { default as startCommand } from "./commands/start";
|
|
15
|
+
|
|
16
|
+
export { unstable_buildBundleWithConfig } from "./commands/bundle/buildBundle";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
declare module.exports: $FlowFixMe;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.KeyPressHandler = void 0;
|
|
7
|
+
var _cliTools = require("@react-native-community/cli-tools");
|
|
8
|
+
/**
|
|
9
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
10
|
+
*
|
|
11
|
+
* This source code is licensed under the MIT license found in the
|
|
12
|
+
* LICENSE file in the root directory of this source tree.
|
|
13
|
+
*
|
|
14
|
+
*
|
|
15
|
+
* @format
|
|
16
|
+
* @oncall react_native
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const CTRL_C = "\u0003";
|
|
20
|
+
|
|
21
|
+
/** An abstract key stroke interceptor. */
|
|
22
|
+
class KeyPressHandler {
|
|
23
|
+
_isInterceptingKeyStrokes = false;
|
|
24
|
+
_isHandlingKeyPress = false;
|
|
25
|
+
constructor(onPress) {
|
|
26
|
+
this._onPress = onPress;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Start observing interaction pause listeners. */
|
|
30
|
+
createInteractionListener() {
|
|
31
|
+
// Support observing prompts.
|
|
32
|
+
let wasIntercepting = false;
|
|
33
|
+
const listener = ({ pause }) => {
|
|
34
|
+
if (pause) {
|
|
35
|
+
// Track if we were already intercepting key strokes before pausing, so we can
|
|
36
|
+
// resume after pausing.
|
|
37
|
+
wasIntercepting = this._isInterceptingKeyStrokes;
|
|
38
|
+
this.stopInterceptingKeyStrokes();
|
|
39
|
+
} else if (wasIntercepting) {
|
|
40
|
+
// Only start if we were previously intercepting.
|
|
41
|
+
this.startInterceptingKeyStrokes();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return listener;
|
|
45
|
+
}
|
|
46
|
+
_handleKeypress = async (key) => {
|
|
47
|
+
// Prevent sending another event until the previous event has finished.
|
|
48
|
+
if (this._isHandlingKeyPress && key !== CTRL_C) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this._isHandlingKeyPress = true;
|
|
52
|
+
try {
|
|
53
|
+
_cliTools.logger.debug(`Key pressed: ${key}`);
|
|
54
|
+
await this._onPress(key);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return new _cliTools.CLIError(
|
|
57
|
+
"There was an error with the key press handler."
|
|
58
|
+
);
|
|
59
|
+
} finally {
|
|
60
|
+
this._isHandlingKeyPress = false;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** Start intercepting all key strokes and passing them to the input `onPress` method. */
|
|
65
|
+
startInterceptingKeyStrokes() {
|
|
66
|
+
if (this._isInterceptingKeyStrokes) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this._isInterceptingKeyStrokes = true;
|
|
70
|
+
const { stdin } = process;
|
|
71
|
+
// $FlowFixMe[prop-missing]
|
|
72
|
+
stdin.setRawMode(true);
|
|
73
|
+
stdin.resume();
|
|
74
|
+
stdin.setEncoding("utf8");
|
|
75
|
+
stdin.on("data", this._handleKeypress);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Stop intercepting all key strokes. */
|
|
79
|
+
stopInterceptingKeyStrokes() {
|
|
80
|
+
if (!this._isInterceptingKeyStrokes) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this._isInterceptingKeyStrokes = false;
|
|
84
|
+
const { stdin } = process;
|
|
85
|
+
stdin.removeListener("data", this._handleKeypress);
|
|
86
|
+
// $FlowFixMe[prop-missing]
|
|
87
|
+
stdin.setRawMode(false);
|
|
88
|
+
stdin.resume();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.KeyPressHandler = KeyPressHandler;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** An abstract key stroke interceptor. */
|
|
13
|
+
declare export class KeyPressHandler {
|
|
14
|
+
_isInterceptingKeyStrokes: $FlowFixMe;
|
|
15
|
+
_isHandlingKeyPress: $FlowFixMe;
|
|
16
|
+
_onPress: (key: string) => Promise<void>;
|
|
17
|
+
constructor(onPress: (key: string) => Promise<void>): void;
|
|
18
|
+
createInteractionListener(): ({ pause: boolean, ... }) => void;
|
|
19
|
+
_handleKeypress: $FlowFixMe;
|
|
20
|
+
startInterceptingKeyStrokes(): void;
|
|
21
|
+
stopInterceptingKeyStrokes(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = isDevServerRunning;
|
|
7
|
+
var _net = _interopRequireDefault(require("net"));
|
|
8
|
+
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
9
|
+
function _interopRequireDefault(obj) {
|
|
10
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14
|
+
*
|
|
15
|
+
* This source code is licensed under the MIT license found in the
|
|
16
|
+
* LICENSE file in the root directory of this source tree.
|
|
17
|
+
*
|
|
18
|
+
*
|
|
19
|
+
* @format
|
|
20
|
+
* @oncall react_native
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Determine whether we can run the dev server.
|
|
25
|
+
*
|
|
26
|
+
* Return values:
|
|
27
|
+
* - `not_running`: The port is unoccupied.
|
|
28
|
+
* - `matched_server_running`: The port is occupied by another instance of this
|
|
29
|
+
* dev server (matching the passed `projectRoot`).
|
|
30
|
+
* - `port_taken`: The port is occupied by another process.
|
|
31
|
+
* - `unknown`: An error was encountered; attempt server creation anyway.
|
|
32
|
+
*/
|
|
33
|
+
async function isDevServerRunning(scheme, host, port, projectRoot) {
|
|
34
|
+
try {
|
|
35
|
+
if (!(await isPortOccupied(host, port))) {
|
|
36
|
+
return "not_running";
|
|
37
|
+
}
|
|
38
|
+
const statusResponse = await (0, _nodeFetch.default)(
|
|
39
|
+
`${scheme}://${host}:${port}/status`
|
|
40
|
+
);
|
|
41
|
+
const body = await statusResponse.text();
|
|
42
|
+
return body === "packager-status:running" &&
|
|
43
|
+
statusResponse.headers.get("X-React-Native-Project-Root") === projectRoot
|
|
44
|
+
? "matched_server_running"
|
|
45
|
+
: "port_taken";
|
|
46
|
+
} catch (e) {
|
|
47
|
+
return "unknown";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function isPortOccupied(host, port) {
|
|
51
|
+
let result = false;
|
|
52
|
+
const server = _net.default.createServer();
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
server.once("error", (e) => {
|
|
55
|
+
server.close();
|
|
56
|
+
if (e.code === "EADDRINUSE") {
|
|
57
|
+
result = true;
|
|
58
|
+
} else {
|
|
59
|
+
reject(e);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
server.once("listening", () => {
|
|
63
|
+
result = false;
|
|
64
|
+
server.close();
|
|
65
|
+
});
|
|
66
|
+
server.once("close", () => {
|
|
67
|
+
resolve(result);
|
|
68
|
+
});
|
|
69
|
+
server.listen({
|
|
70
|
+
host,
|
|
71
|
+
port,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Determine whether we can run the dev server.
|
|
14
|
+
*
|
|
15
|
+
* Return values:
|
|
16
|
+
* - `not_running`: The port is unoccupied.
|
|
17
|
+
* - `matched_server_running`: The port is occupied by another instance of this
|
|
18
|
+
* dev server (matching the passed `projectRoot`).
|
|
19
|
+
* - `port_taken`: The port is occupied by another process.
|
|
20
|
+
* - `unknown`: An error was encountered; attempt server creation anyway.
|
|
21
|
+
*/
|
|
22
|
+
declare export default function isDevServerRunning(
|
|
23
|
+
scheme: string,
|
|
24
|
+
host: string,
|
|
25
|
+
port: number,
|
|
26
|
+
projectRoot: string
|
|
27
|
+
): Promise<"not_running" | "matched_server_running" | "port_taken" | "unknown">;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = loadMetroConfig;
|
|
7
|
+
var _path = _interopRequireDefault(require("path"));
|
|
8
|
+
var _metroConfig = require("metro-config");
|
|
9
|
+
var _cliTools = require("@react-native-community/cli-tools");
|
|
10
|
+
var _metroPlatformResolver = require("./metroPlatformResolver");
|
|
11
|
+
function _interopRequireDefault(obj) {
|
|
12
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
16
|
+
*
|
|
17
|
+
* This source code is licensed under the MIT license found in the
|
|
18
|
+
* LICENSE file in the root directory of this source tree.
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
* @format
|
|
22
|
+
* @oncall react_native
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get the config options to override based on RN CLI inputs.
|
|
27
|
+
*/
|
|
28
|
+
function getOverrideConfig(ctx) {
|
|
29
|
+
const outOfTreePlatforms = Object.keys(ctx.platforms).filter(
|
|
30
|
+
(platform) => ctx.platforms[platform].npmPackageName
|
|
31
|
+
);
|
|
32
|
+
const resolver = {
|
|
33
|
+
platforms: [...Object.keys(ctx.platforms), "native"],
|
|
34
|
+
};
|
|
35
|
+
if (outOfTreePlatforms.length) {
|
|
36
|
+
resolver.resolveRequest = (0,
|
|
37
|
+
_metroPlatformResolver.reactNativePlatformResolver)(
|
|
38
|
+
outOfTreePlatforms.reduce((result, platform) => {
|
|
39
|
+
result[platform] = ctx.platforms[platform].npmPackageName;
|
|
40
|
+
return result;
|
|
41
|
+
}, {})
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
resolver,
|
|
46
|
+
serializer: {
|
|
47
|
+
// We can include multiple copies of InitializeCore here because metro will
|
|
48
|
+
// only add ones that are already part of the bundle
|
|
49
|
+
getModulesRunBeforeMainModule: () => [
|
|
50
|
+
require.resolve(
|
|
51
|
+
_path.default.join(
|
|
52
|
+
ctx.reactNativePath,
|
|
53
|
+
"Libraries/Core/InitializeCore"
|
|
54
|
+
),
|
|
55
|
+
{
|
|
56
|
+
paths: [ctx.root],
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
...outOfTreePlatforms.map((platform) =>
|
|
60
|
+
require.resolve(
|
|
61
|
+
`${ctx.platforms[platform].npmPackageName}/Libraries/Core/InitializeCore`
|
|
62
|
+
)
|
|
63
|
+
),
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Load Metro config.
|
|
71
|
+
*
|
|
72
|
+
* Allows the CLI to override select values in `metro.config.js` based on
|
|
73
|
+
* dynamic user options in `ctx`.
|
|
74
|
+
*/
|
|
75
|
+
async function loadMetroConfig(ctx, options = {}) {
|
|
76
|
+
const overrideConfig = getOverrideConfig(ctx);
|
|
77
|
+
const cwd = ctx.root;
|
|
78
|
+
const projectConfig = await (0, _metroConfig.resolveConfig)(
|
|
79
|
+
options.config,
|
|
80
|
+
cwd
|
|
81
|
+
);
|
|
82
|
+
if (projectConfig.isEmpty) {
|
|
83
|
+
throw new _cliTools.CLIError(`No Metro config found in ${cwd}`);
|
|
84
|
+
}
|
|
85
|
+
_cliTools.logger.debug(`Reading Metro config from ${projectConfig.filepath}`);
|
|
86
|
+
if (!global.__REACT_NATIVE_METRO_CONFIG_LOADED) {
|
|
87
|
+
for (const line of `
|
|
88
|
+
=================================================================================================
|
|
89
|
+
From React Native 0.73, your project's Metro config should extend '@react-native/metro-config'
|
|
90
|
+
or it will fail to build. Please copy the template at:
|
|
91
|
+
https://github.com/facebook/react-native/blob/main/packages/react-native/template/metro.config.js
|
|
92
|
+
This warning will be removed in future (https://github.com/facebook/metro/issues/1018).
|
|
93
|
+
=================================================================================================
|
|
94
|
+
`
|
|
95
|
+
.trim()
|
|
96
|
+
.split("\n")) {
|
|
97
|
+
_cliTools.logger.warn(line);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return (0, _metroConfig.mergeConfig)(
|
|
101
|
+
await (0, _metroConfig.loadConfig)({
|
|
102
|
+
cwd,
|
|
103
|
+
...options,
|
|
104
|
+
}),
|
|
105
|
+
overrideConfig
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { Config } from "@react-native-community/cli-types";
|
|
13
|
+
import type { ConfigT, YargArguments } from "metro-config";
|
|
14
|
+
|
|
15
|
+
export type { Config };
|
|
16
|
+
|
|
17
|
+
export type ConfigLoadingContext = $ReadOnly<{
|
|
18
|
+
root: Config["root"],
|
|
19
|
+
reactNativePath: Config["reactNativePath"],
|
|
20
|
+
platforms: Config["platforms"],
|
|
21
|
+
...
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Load Metro config.
|
|
26
|
+
*
|
|
27
|
+
* Allows the CLI to override select values in `metro.config.js` based on
|
|
28
|
+
* dynamic user options in `ctx`.
|
|
29
|
+
*/
|
|
30
|
+
declare export default function loadMetroConfig(
|
|
31
|
+
ctx: ConfigLoadingContext,
|
|
32
|
+
options: YargArguments
|
|
33
|
+
): Promise<ConfigT>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.reactNativePlatformResolver = reactNativePlatformResolver;
|
|
7
|
+
/**
|
|
8
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
9
|
+
*
|
|
10
|
+
* This source code is licensed under the MIT license found in the
|
|
11
|
+
* LICENSE file in the root directory of this source tree.
|
|
12
|
+
*
|
|
13
|
+
*
|
|
14
|
+
* @format
|
|
15
|
+
* @oncall react_native
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This is an implementation of a metro resolveRequest option which will remap react-native imports
|
|
20
|
+
* to different npm packages based on the platform requested. This allows a single metro instance/config
|
|
21
|
+
* to produce bundles for multiple out of tree platforms at a time.
|
|
22
|
+
*
|
|
23
|
+
* @param platformImplementations
|
|
24
|
+
* A map of platform to npm package that implements that platform
|
|
25
|
+
*
|
|
26
|
+
* Ex:
|
|
27
|
+
* {
|
|
28
|
+
* windows: 'react-native-windows'
|
|
29
|
+
* macos: 'react-native-macos'
|
|
30
|
+
* }
|
|
31
|
+
*/
|
|
32
|
+
function reactNativePlatformResolver(platformImplementations) {
|
|
33
|
+
return (context, moduleName, platform) => {
|
|
34
|
+
let modifiedModuleName = moduleName;
|
|
35
|
+
if (platform != null && platformImplementations[platform]) {
|
|
36
|
+
if (moduleName === "react-native") {
|
|
37
|
+
modifiedModuleName = platformImplementations[platform];
|
|
38
|
+
} else if (moduleName.startsWith("react-native/")) {
|
|
39
|
+
modifiedModuleName = `${
|
|
40
|
+
platformImplementations[platform]
|
|
41
|
+
}/${modifiedModuleName.slice("react-native/".length)}`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return context.resolveRequest(context, modifiedModuleName, platform);
|
|
45
|
+
};
|
|
46
|
+
}
|