@react-native/dev-middleware 0.73.0
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 +11 -0
- package/dist/createDevMiddleware.js +35 -0
- package/dist/createDevMiddleware.js.flow +31 -0
- package/dist/index.flow.js +17 -0
- package/dist/index.flow.js.flow +12 -0
- package/dist/index.js +3 -0
- package/dist/index.js.flow +20 -0
- package/dist/middleware/openDebuggerMiddleware.js +82 -0
- package/dist/middleware/openDebuggerMiddleware.js.flow +87 -0
- package/dist/types/Logger.js +1 -0
- package/dist/types/Logger.js.flow +17 -0
- package/dist/utils/getDevServerUrl.js +37 -0
- package/dist/utils/getDevServerUrl.js.flow +32 -0
- package/dist/utils/launchChromeDevTools.js +44 -0
- package/dist/utils/launchChromeDevTools.js.flow +38 -0
- package/dist/utils/launchDebuggerAppWindow.js +58 -0
- package/dist/utils/launchDebuggerAppWindow.js.flow +56 -0
- package/dist/utils/queryInspectorTargets.js +35 -0
- package/dist/utils/queryInspectorTargets.js.flow +40 -0
- package/package.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @react-native/dev-middleware
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Dev server middleware supporting core React Native development features. This package is preconfigured in all React Native projects.
|
|
6
|
+
|
|
7
|
+
## Endpoints
|
|
8
|
+
|
|
9
|
+
### `/open-debugger`
|
|
10
|
+
|
|
11
|
+
Open the JavaScript debugger for a given CDP target (direct Hermes debugging).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = createDevMiddleware;
|
|
7
|
+
var _connect = _interopRequireDefault(require("connect"));
|
|
8
|
+
var _openDebuggerMiddleware = _interopRequireDefault(
|
|
9
|
+
require("./middleware/openDebuggerMiddleware")
|
|
10
|
+
);
|
|
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
|
+
function createDevMiddleware({ logger } = {}) {
|
|
26
|
+
const middleware = (0, _connect.default)().use(
|
|
27
|
+
"/open-debugger",
|
|
28
|
+
(0, _openDebuggerMiddleware.default)({
|
|
29
|
+
logger,
|
|
30
|
+
})
|
|
31
|
+
);
|
|
32
|
+
return {
|
|
33
|
+
middleware,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {NextHandleFunction} from 'connect';
|
|
13
|
+
import type {Logger} from './types/Logger';
|
|
14
|
+
|
|
15
|
+
import connect from 'connect';
|
|
16
|
+
import openDebuggerMiddleware from './middleware/openDebuggerMiddleware';
|
|
17
|
+
|
|
18
|
+
type Options = $ReadOnly<{
|
|
19
|
+
logger?: Logger,
|
|
20
|
+
}>;
|
|
21
|
+
|
|
22
|
+
export default function createDevMiddleware({logger}: Options = {}): {
|
|
23
|
+
middleware: NextHandleFunction,
|
|
24
|
+
} {
|
|
25
|
+
const middleware = connect().use(
|
|
26
|
+
'/open-debugger',
|
|
27
|
+
openDebuggerMiddleware({logger}),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return {middleware};
|
|
31
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "createDevMiddleware", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _createDevMiddleware.default;
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
var _createDevMiddleware = _interopRequireDefault(
|
|
13
|
+
require("./createDevMiddleware")
|
|
14
|
+
);
|
|
15
|
+
function _interopRequireDefault(obj) {
|
|
16
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
17
|
+
}
|
|
@@ -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 strict
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export {default as createDevMiddleware} from './createDevMiddleware';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
/*::
|
|
13
|
+
export type * from './index.flow';
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
if (!process.env.BUILD_EXCLUDE_BABEL_REGISTER) {
|
|
17
|
+
require('../../../scripts/build/babel-register').registerForMonorepo();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = require('./index.flow');
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = openDebuggerMiddleware;
|
|
7
|
+
var _url = _interopRequireDefault(require("url"));
|
|
8
|
+
var _getDevServerUrl = _interopRequireDefault(
|
|
9
|
+
require("../utils/getDevServerUrl")
|
|
10
|
+
);
|
|
11
|
+
var _launchChromeDevTools = _interopRequireDefault(
|
|
12
|
+
require("../utils/launchChromeDevTools")
|
|
13
|
+
);
|
|
14
|
+
var _queryInspectorTargets = _interopRequireDefault(
|
|
15
|
+
require("../utils/queryInspectorTargets")
|
|
16
|
+
);
|
|
17
|
+
function _interopRequireDefault(obj) {
|
|
18
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
22
|
+
*
|
|
23
|
+
* This source code is licensed under the MIT license found in the
|
|
24
|
+
* LICENSE file in the root directory of this source tree.
|
|
25
|
+
*
|
|
26
|
+
*
|
|
27
|
+
* @format
|
|
28
|
+
* @oncall react_native
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const debuggerInstances = new Map();
|
|
32
|
+
/**
|
|
33
|
+
* Open the JavaScript debugger for a given CDP target (direct Hermes debugging).
|
|
34
|
+
*
|
|
35
|
+
* Currently supports Hermes targets, opening debugger websocket URL in Chrome
|
|
36
|
+
* DevTools.
|
|
37
|
+
*
|
|
38
|
+
* @see https://chromedevtools.github.io/devtools-protocol/
|
|
39
|
+
*/
|
|
40
|
+
function openDebuggerMiddleware({ logger }) {
|
|
41
|
+
return async (req, res, next) => {
|
|
42
|
+
if (req.method === "POST") {
|
|
43
|
+
const { query } = _url.default.parse(req.url, true);
|
|
44
|
+
const { appId } = query;
|
|
45
|
+
if (typeof appId !== "string") {
|
|
46
|
+
res.writeHead(400);
|
|
47
|
+
res.end();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const targets = await (0, _queryInspectorTargets.default)(
|
|
51
|
+
(0, _getDevServerUrl.default)(req)
|
|
52
|
+
);
|
|
53
|
+
const target = targets.find((_target) => _target.description === appId);
|
|
54
|
+
if (!target) {
|
|
55
|
+
res.writeHead(404);
|
|
56
|
+
res.end("Unable to find Chrome DevTools inspector target");
|
|
57
|
+
logger?.warn(
|
|
58
|
+
"No compatible apps connected. JavaScript debugging can only be used with the Hermes engine."
|
|
59
|
+
);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
logger?.info("Launching JS debugger...");
|
|
64
|
+
debuggerInstances.get(appId)?.kill();
|
|
65
|
+
debuggerInstances.set(
|
|
66
|
+
appId,
|
|
67
|
+
await (0, _launchChromeDevTools.default)(target.webSocketDebuggerUrl)
|
|
68
|
+
);
|
|
69
|
+
res.end();
|
|
70
|
+
return;
|
|
71
|
+
} catch (e) {
|
|
72
|
+
logger?.error(
|
|
73
|
+
"Error launching JS debugger: " + e.message ?? "Unknown error"
|
|
74
|
+
);
|
|
75
|
+
res.writeHead(500);
|
|
76
|
+
res.end();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
next();
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {LaunchedChrome} from 'chrome-launcher';
|
|
13
|
+
import type {NextHandleFunction} from 'connect';
|
|
14
|
+
import type {IncomingMessage, ServerResponse} from 'http';
|
|
15
|
+
import type {Logger} from '../types/Logger';
|
|
16
|
+
|
|
17
|
+
import url from 'url';
|
|
18
|
+
import getDevServerUrl from '../utils/getDevServerUrl';
|
|
19
|
+
import launchChromeDevTools from '../utils/launchChromeDevTools';
|
|
20
|
+
import queryInspectorTargets from '../utils/queryInspectorTargets';
|
|
21
|
+
|
|
22
|
+
const debuggerInstances = new Map<string, LaunchedChrome>();
|
|
23
|
+
|
|
24
|
+
type Options = $ReadOnly<{
|
|
25
|
+
logger?: Logger,
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Open the JavaScript debugger for a given CDP target (direct Hermes debugging).
|
|
30
|
+
*
|
|
31
|
+
* Currently supports Hermes targets, opening debugger websocket URL in Chrome
|
|
32
|
+
* DevTools.
|
|
33
|
+
*
|
|
34
|
+
* @see https://chromedevtools.github.io/devtools-protocol/
|
|
35
|
+
*/
|
|
36
|
+
export default function openDebuggerMiddleware({
|
|
37
|
+
logger,
|
|
38
|
+
}: Options): NextHandleFunction {
|
|
39
|
+
return async (
|
|
40
|
+
req: IncomingMessage,
|
|
41
|
+
res: ServerResponse,
|
|
42
|
+
next: (err?: Error) => void,
|
|
43
|
+
) => {
|
|
44
|
+
if (req.method === 'POST') {
|
|
45
|
+
const {query} = url.parse(req.url, true);
|
|
46
|
+
const {appId} = query;
|
|
47
|
+
|
|
48
|
+
if (typeof appId !== 'string') {
|
|
49
|
+
res.writeHead(400);
|
|
50
|
+
res.end();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const targets = await queryInspectorTargets(getDevServerUrl(req));
|
|
55
|
+
const target = targets.find(_target => _target.description === appId);
|
|
56
|
+
|
|
57
|
+
if (!target) {
|
|
58
|
+
res.writeHead(404);
|
|
59
|
+
res.end('Unable to find Chrome DevTools inspector target');
|
|
60
|
+
logger?.warn(
|
|
61
|
+
'No compatible apps connected. JavaScript debugging can only be used with the Hermes engine.',
|
|
62
|
+
);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
logger?.info('Launching JS debugger...');
|
|
68
|
+
debuggerInstances.get(appId)?.kill();
|
|
69
|
+
debuggerInstances.set(
|
|
70
|
+
appId,
|
|
71
|
+
await launchChromeDevTools(target.webSocketDebuggerUrl),
|
|
72
|
+
);
|
|
73
|
+
res.end();
|
|
74
|
+
return;
|
|
75
|
+
} catch (e) {
|
|
76
|
+
logger?.error(
|
|
77
|
+
'Error launching JS debugger: ' + e.message ?? 'Unknown error',
|
|
78
|
+
);
|
|
79
|
+
res.writeHead(500);
|
|
80
|
+
res.end();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
next();
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export type Logger = $ReadOnly<{
|
|
13
|
+
error: (...message: Array<string>) => void,
|
|
14
|
+
info: (...message: Array<string>) => void,
|
|
15
|
+
warn: (...message: Array<string>) => void,
|
|
16
|
+
...
|
|
17
|
+
}>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = getDevServerUrl;
|
|
7
|
+
var _net = _interopRequireDefault(require("net"));
|
|
8
|
+
var _tls = require("tls");
|
|
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
|
+
* Get the base URL to address the current development server.
|
|
25
|
+
*/
|
|
26
|
+
function getDevServerUrl(req) {
|
|
27
|
+
const scheme =
|
|
28
|
+
req.socket instanceof _tls.TLSSocket && req.socket.encrypted === true
|
|
29
|
+
? "https"
|
|
30
|
+
: "http";
|
|
31
|
+
const { localAddress, localPort } = req.socket;
|
|
32
|
+
const address =
|
|
33
|
+
localAddress && _net.default.isIPv6(localAddress)
|
|
34
|
+
? `[${localAddress}]`
|
|
35
|
+
: localAddress;
|
|
36
|
+
return `${scheme}:${address}:${localPort}`;
|
|
37
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {IncomingMessage} from 'http';
|
|
13
|
+
|
|
14
|
+
import net from 'net';
|
|
15
|
+
import {TLSSocket} from 'tls';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the base URL to address the current development server.
|
|
19
|
+
*/
|
|
20
|
+
export default function getDevServerUrl(req: IncomingMessage): string {
|
|
21
|
+
const scheme =
|
|
22
|
+
req.socket instanceof TLSSocket && req.socket.encrypted === true
|
|
23
|
+
? 'https'
|
|
24
|
+
: 'http';
|
|
25
|
+
const {localAddress, localPort} = req.socket;
|
|
26
|
+
const address =
|
|
27
|
+
localAddress && net.isIPv6(localAddress)
|
|
28
|
+
? `[${localAddress}]`
|
|
29
|
+
: localAddress;
|
|
30
|
+
|
|
31
|
+
return `${scheme}:${address}:${localPort}`;
|
|
32
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = launchChromeDevTools;
|
|
7
|
+
var _launchDebuggerAppWindow = _interopRequireDefault(
|
|
8
|
+
require("./launchDebuggerAppWindow")
|
|
9
|
+
);
|
|
10
|
+
function _interopRequireDefault(obj) {
|
|
11
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
15
|
+
*
|
|
16
|
+
* This source code is licensed under the MIT license found in the
|
|
17
|
+
* LICENSE file in the root directory of this source tree.
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
* @format
|
|
21
|
+
* @oncall react_native
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The Chrome DevTools frontend revision to use. This should be set to the
|
|
26
|
+
* latest version known to be compatible with Hermes.
|
|
27
|
+
*
|
|
28
|
+
* Revision should be the full identifier from:
|
|
29
|
+
* https://chromium.googlesource.com/chromium/src.git
|
|
30
|
+
*/
|
|
31
|
+
const DEVTOOLS_FRONTEND_REV = "d9568d04d7dd79269c5a655d7ada69650c5a8336"; // Chrome 100.0.4896.75
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Attempt to launch Chrome DevTools on the host machine for a given CDP target.
|
|
35
|
+
*/
|
|
36
|
+
async function launchChromeDevTools(webSocketDebuggerUrl) {
|
|
37
|
+
const ws = webSocketDebuggerUrl.replace(/^ws:\/\//, "");
|
|
38
|
+
return (0, _launchDebuggerAppWindow.default)(
|
|
39
|
+
`${`https://chrome-devtools-frontend.appspot.com/serve_rev/@${DEVTOOLS_FRONTEND_REV}/devtools_app.html`}?panel=console&ws=${encodeURIComponent(
|
|
40
|
+
ws
|
|
41
|
+
)}`,
|
|
42
|
+
"open-debugger"
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -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
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {LaunchedChrome} from 'chrome-launcher';
|
|
13
|
+
|
|
14
|
+
import launchDebuggerAppWindow from './launchDebuggerAppWindow';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The Chrome DevTools frontend revision to use. This should be set to the
|
|
18
|
+
* latest version known to be compatible with Hermes.
|
|
19
|
+
*
|
|
20
|
+
* Revision should be the full identifier from:
|
|
21
|
+
* https://chromium.googlesource.com/chromium/src.git
|
|
22
|
+
*/
|
|
23
|
+
const DEVTOOLS_FRONTEND_REV = 'd9568d04d7dd79269c5a655d7ada69650c5a8336'; // Chrome 100.0.4896.75
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Attempt to launch Chrome DevTools on the host machine for a given CDP target.
|
|
27
|
+
*/
|
|
28
|
+
export default async function launchChromeDevTools(
|
|
29
|
+
webSocketDebuggerUrl: string,
|
|
30
|
+
): Promise<LaunchedChrome> {
|
|
31
|
+
const urlBase = `https://chrome-devtools-frontend.appspot.com/serve_rev/@${DEVTOOLS_FRONTEND_REV}/devtools_app.html`;
|
|
32
|
+
const ws = webSocketDebuggerUrl.replace(/^ws:\/\//, '');
|
|
33
|
+
|
|
34
|
+
return launchDebuggerAppWindow(
|
|
35
|
+
`${urlBase}?panel=console&ws=${encodeURIComponent(ws)}`,
|
|
36
|
+
'open-debugger',
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = launchDebuggerAppWindow;
|
|
7
|
+
var _fs = require("fs");
|
|
8
|
+
var _path = _interopRequireDefault(require("path"));
|
|
9
|
+
var _tempDir = _interopRequireDefault(require("temp-dir"));
|
|
10
|
+
function _interopRequireDefault(obj) {
|
|
11
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
15
|
+
*
|
|
16
|
+
* This source code is licensed under the MIT license found in the
|
|
17
|
+
* LICENSE file in the root directory of this source tree.
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
* @format
|
|
21
|
+
* @oncall react_native
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const ChromeLauncher = require("chrome-launcher");
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Attempt to open a debugger frontend URL as a Google Chrome app window.
|
|
28
|
+
*/
|
|
29
|
+
async function launchDebuggerAppWindow(
|
|
30
|
+
url,
|
|
31
|
+
/**
|
|
32
|
+
* Used to construct the temp browser dir to preserve settings such as window
|
|
33
|
+
* position.
|
|
34
|
+
*/
|
|
35
|
+
intent
|
|
36
|
+
) {
|
|
37
|
+
const userDataDir = await createTempDir(`react-native-${intent}-${"chrome"}`);
|
|
38
|
+
try {
|
|
39
|
+
return ChromeLauncher.launch({
|
|
40
|
+
chromeFlags: [
|
|
41
|
+
`--app=${url}`,
|
|
42
|
+
`--user-data-dir=${userDataDir}`,
|
|
43
|
+
"--window-size=1200,600",
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
} catch (e) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
"Unable to find a browser on the host to open the debugger. Supported browsers: Google Chrome"
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function createTempDir(dirName) {
|
|
53
|
+
const tempDir = _path.default.join(_tempDir.default, dirName);
|
|
54
|
+
await _fs.promises.mkdir(tempDir, {
|
|
55
|
+
recursive: true,
|
|
56
|
+
});
|
|
57
|
+
return tempDir;
|
|
58
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {LaunchedChrome} from 'chrome-launcher';
|
|
13
|
+
import {promises as fs} from 'fs';
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import osTempDir from 'temp-dir';
|
|
16
|
+
|
|
17
|
+
const ChromeLauncher = require('chrome-launcher');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Attempt to open a debugger frontend URL as a Google Chrome app window.
|
|
21
|
+
*/
|
|
22
|
+
export default async function launchDebuggerAppWindow(
|
|
23
|
+
url: string,
|
|
24
|
+
/**
|
|
25
|
+
* Used to construct the temp browser dir to preserve settings such as window
|
|
26
|
+
* position.
|
|
27
|
+
*/
|
|
28
|
+
intent: 'open-debugger',
|
|
29
|
+
): Promise<LaunchedChrome> {
|
|
30
|
+
const browserType = 'chrome';
|
|
31
|
+
const userDataDir = await createTempDir(
|
|
32
|
+
`react-native-${intent}-${browserType}`,
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
return ChromeLauncher.launch({
|
|
37
|
+
chromeFlags: [
|
|
38
|
+
`--app=${url}`,
|
|
39
|
+
`--user-data-dir=${userDataDir}`,
|
|
40
|
+
'--window-size=1200,600',
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
} catch (e) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
'Unable to find a browser on the host to open the debugger. Supported browsers: Google Chrome',
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function createTempDir(dirName: string): Promise<string> {
|
|
51
|
+
const tempDir = path.join(osTempDir, dirName);
|
|
52
|
+
|
|
53
|
+
await fs.mkdir(tempDir, {recursive: true});
|
|
54
|
+
|
|
55
|
+
return tempDir;
|
|
56
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = queryInspectorTargets;
|
|
7
|
+
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
8
|
+
function _interopRequireDefault(obj) {
|
|
9
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the MIT license found in the
|
|
15
|
+
* LICENSE file in the root directory of this source tree.
|
|
16
|
+
*
|
|
17
|
+
*
|
|
18
|
+
* @format
|
|
19
|
+
* @oncall react_native
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get the list of available debug targets from the React Native dev server.
|
|
24
|
+
*
|
|
25
|
+
* @see https://chromedevtools.github.io/devtools-protocol/
|
|
26
|
+
*/
|
|
27
|
+
async function queryInspectorTargets(devServerUrl) {
|
|
28
|
+
const res = await (0, _nodeFetch.default)(`${devServerUrl}/json/list`);
|
|
29
|
+
const apps = await res.json();
|
|
30
|
+
|
|
31
|
+
// Only use targets with better reloading support
|
|
32
|
+
return apps.filter(
|
|
33
|
+
(app) => app.title === "React Native Experimental (Improved Chrome Reloads)"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fetch from 'node-fetch';
|
|
13
|
+
|
|
14
|
+
type ReactNativeCDPTarget = {
|
|
15
|
+
id: string,
|
|
16
|
+
description: string,
|
|
17
|
+
title: string,
|
|
18
|
+
type: string,
|
|
19
|
+
devtoolsFrontendUrl: string,
|
|
20
|
+
webSocketDebuggerUrl: string,
|
|
21
|
+
vm: string,
|
|
22
|
+
deviceName?: string,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get the list of available debug targets from the React Native dev server.
|
|
27
|
+
*
|
|
28
|
+
* @see https://chromedevtools.github.io/devtools-protocol/
|
|
29
|
+
*/
|
|
30
|
+
export default async function queryInspectorTargets(
|
|
31
|
+
devServerUrl: string,
|
|
32
|
+
): Promise<ReactNativeCDPTarget[]> {
|
|
33
|
+
const res = await fetch(`${devServerUrl}/json/list`);
|
|
34
|
+
const apps = (await res.json(): Array<ReactNativeCDPTarget>);
|
|
35
|
+
|
|
36
|
+
// Only use targets with better reloading support
|
|
37
|
+
return apps.filter(
|
|
38
|
+
app => app.title === 'React Native Experimental (Improved Chrome Reloads)',
|
|
39
|
+
);
|
|
40
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-native/dev-middleware",
|
|
3
|
+
"version": "0.73.0",
|
|
4
|
+
"description": "Dev server middleware for React Native",
|
|
5
|
+
"keywords": ["react-native", "tools"],
|
|
6
|
+
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/dev-middleware#readme",
|
|
7
|
+
"bugs": "https://github.com/facebook/react-native/issues",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/facebook/react-native.git",
|
|
11
|
+
"directory": "packages/dev-middleware"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"exports": { ".": "./dist/index.js", "./package.json": "./package.json" },
|
|
15
|
+
"files": ["dist"],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"chrome-launcher": "^0.15.2",
|
|
18
|
+
"connect": "^3.6.5",
|
|
19
|
+
"node-fetch": "^2.2.0",
|
|
20
|
+
"temp-dir": "^2.0.0"
|
|
21
|
+
},
|
|
22
|
+
"engines": { "node": ">=18" }
|
|
23
|
+
}
|