metro 0.76.1 → 0.76.2
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/package.json +21 -23
- package/src/DeltaBundler/Serializers/baseJSBundle.js +1 -0
- package/src/DeltaBundler/Serializers/baseJSBundle.js.flow +1 -0
- package/src/DeltaBundler/Serializers/helpers/js.js +22 -6
- package/src/DeltaBundler/Serializers/helpers/js.js.flow +24 -6
- package/src/DeltaBundler/Serializers/helpers/processModules.js +2 -0
- package/src/DeltaBundler/Serializers/helpers/processModules.js.flow +3 -0
- package/src/DeltaBundler/Serializers/hmrJSBundle.js +1 -0
- package/src/DeltaBundler/Serializers/hmrJSBundle.js.flow +1 -0
- package/src/DeltaBundler/types.d.ts +4 -2
- package/src/Server/symbolicate.js +33 -5
- package/src/Server/symbolicate.js.flow +40 -9
- package/src/Server.js +5 -3
- package/src/Server.js.flow +4 -2
- package/src/index.d.ts +16 -6
- package/src/index.flow.js +9 -2
- package/src/index.flow.js.flow +23 -4
- package/src/node-haste/DependencyGraph.js +6 -1
- package/src/node-haste/DependencyGraph.js.flow +7 -1
- package/src/shared/types.flow.js.flow +0 -1
- package/types/Asset.d.ts +0 -25
- package/types/Bundler.d.ts +0 -39
- package/types/DeltaBundler/Graph.d.ts +0 -40
- package/types/DeltaBundler/Serializers/getRamBundleInfo.d.ts +0 -18
- package/types/DeltaBundler/Worker.d.ts +0 -47
- package/types/DeltaBundler/types.d.ts +0 -167
- package/types/DeltaBundler.d.ts +0 -58
- package/types/IncrementalBundler.d.ts +0 -97
- package/types/ModuleGraph/worker/collectDependencies.d.ts +0 -27
- package/types/Server/MultipartResponse.d.ts +0 -31
- package/types/Server.d.ts +0 -113
- package/types/index.d.ts +0 -151
- package/types/lib/CountingSet.d.ts +0 -48
- package/types/lib/TerminalReporter.d.ts +0 -27
- package/types/lib/contextModule.d.ts +0 -22
- package/types/lib/getGraphId.d.ts +0 -11
- package/types/lib/reporting.d.ts +0 -140
- package/types/node-haste/DependencyGraph.d.ts +0 -59
- package/types/shared/output/bundle.d.ts +0 -31
- package/types/shared/types.d.ts +0 -138
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metro",
|
|
3
|
-
"version": "0.76.
|
|
3
|
+
"version": "0.76.2",
|
|
4
4
|
"description": "🚇 The JavaScript bundler for React Native.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": "src/cli.js",
|
|
@@ -34,22 +34,22 @@
|
|
|
34
34
|
"invariant": "^2.2.4",
|
|
35
35
|
"jest-worker": "^27.2.0",
|
|
36
36
|
"lodash.throttle": "^4.1.1",
|
|
37
|
-
"metro-babel-transformer": "0.76.
|
|
38
|
-
"metro-cache": "0.76.
|
|
39
|
-
"metro-cache-key": "0.76.
|
|
40
|
-
"metro-config": "0.76.
|
|
41
|
-
"metro-core": "0.76.
|
|
42
|
-
"metro-file-map": "0.76.
|
|
43
|
-
"metro-inspector-proxy": "0.76.
|
|
44
|
-
"metro-minify-terser": "0.76.
|
|
45
|
-
"metro-minify-uglify": "0.76.
|
|
46
|
-
"metro-react-native-babel-preset": "0.76.
|
|
47
|
-
"metro-resolver": "0.76.
|
|
48
|
-
"metro-runtime": "0.76.
|
|
49
|
-
"metro-source-map": "0.76.
|
|
50
|
-
"metro-symbolicate": "0.76.
|
|
51
|
-
"metro-transform-plugins": "0.76.
|
|
52
|
-
"metro-transform-worker": "0.76.
|
|
37
|
+
"metro-babel-transformer": "0.76.2",
|
|
38
|
+
"metro-cache": "0.76.2",
|
|
39
|
+
"metro-cache-key": "0.76.2",
|
|
40
|
+
"metro-config": "0.76.2",
|
|
41
|
+
"metro-core": "0.76.2",
|
|
42
|
+
"metro-file-map": "0.76.2",
|
|
43
|
+
"metro-inspector-proxy": "0.76.2",
|
|
44
|
+
"metro-minify-terser": "0.76.2",
|
|
45
|
+
"metro-minify-uglify": "0.76.2",
|
|
46
|
+
"metro-react-native-babel-preset": "0.76.2",
|
|
47
|
+
"metro-resolver": "0.76.2",
|
|
48
|
+
"metro-runtime": "0.76.2",
|
|
49
|
+
"metro-source-map": "0.76.2",
|
|
50
|
+
"metro-symbolicate": "0.76.2",
|
|
51
|
+
"metro-transform-plugins": "0.76.2",
|
|
52
|
+
"metro-transform-worker": "0.76.2",
|
|
53
53
|
"mime-types": "^2.1.27",
|
|
54
54
|
"node-fetch": "^2.2.0",
|
|
55
55
|
"nullthrows": "^1.1.1",
|
|
@@ -63,16 +63,14 @@
|
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
|
|
66
|
-
"@types/babel__code-frame": "^7.0.3",
|
|
67
|
-
"@types/ws": "^8.5.4",
|
|
68
66
|
"babel-jest": "^29.2.1",
|
|
69
67
|
"dedent": "^0.7.0",
|
|
70
68
|
"jest-snapshot": "^26.5.2",
|
|
71
69
|
"jest-snapshot-serializer-raw": "^1.2.0",
|
|
72
|
-
"metro-babel-register": "0.76.
|
|
73
|
-
"metro-memory-fs": "0.76.
|
|
74
|
-
"metro-react-native-babel-preset": "0.76.
|
|
75
|
-
"metro-react-native-babel-transformer": "0.76.
|
|
70
|
+
"metro-babel-register": "0.76.2",
|
|
71
|
+
"metro-memory-fs": "0.76.2",
|
|
72
|
+
"metro-react-native-babel-preset": "0.76.2",
|
|
73
|
+
"metro-react-native-babel-transformer": "0.76.2",
|
|
76
74
|
"mock-req": "^0.2.0",
|
|
77
75
|
"mock-res": "^0.6.0",
|
|
78
76
|
"stack-trace": "^0.0.10"
|
|
@@ -24,6 +24,7 @@ function baseJSBundle(entryPoint, preModules, graph, options) {
|
|
|
24
24
|
includeAsyncPaths: options.includeAsyncPaths,
|
|
25
25
|
projectRoot: options.projectRoot,
|
|
26
26
|
serverRoot: options.serverRoot,
|
|
27
|
+
sourceUrl: options.sourceUrl,
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
// Do not prepend polyfills or the require runtime when only modules are requested
|
|
@@ -39,6 +39,7 @@ function baseJSBundle(
|
|
|
39
39
|
includeAsyncPaths: options.includeAsyncPaths,
|
|
40
40
|
projectRoot: options.projectRoot,
|
|
41
41
|
serverRoot: options.serverRoot,
|
|
42
|
+
sourceUrl: options.sourceUrl,
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
// Do not prepend polyfills or the require runtime when only modules are requested
|
|
@@ -31,16 +31,32 @@ function getModuleParams(module, options) {
|
|
|
31
31
|
const id = options.createModuleId(dependency.absolutePath);
|
|
32
32
|
if (options.includeAsyncPaths && dependency.data.data.asyncType != null) {
|
|
33
33
|
hasPaths = true;
|
|
34
|
+
invariant(
|
|
35
|
+
options.sourceUrl != null,
|
|
36
|
+
"sourceUrl is required when includeAsyncPaths is true"
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// TODO: Only include path if the target is not in the bundle
|
|
40
|
+
|
|
41
|
+
// Construct a server-relative URL for the split bundle, propagating
|
|
42
|
+
// most parameters from the main bundle's URL.
|
|
43
|
+
|
|
44
|
+
const { searchParams } = new URL(options.sourceUrl);
|
|
45
|
+
searchParams.set("modulesOnly", "true");
|
|
46
|
+
searchParams.set("runModule", "false");
|
|
34
47
|
const bundlePath = path.relative(
|
|
35
48
|
options.serverRoot,
|
|
36
49
|
dependency.absolutePath
|
|
37
50
|
);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
51
|
+
paths[id] =
|
|
52
|
+
"/" +
|
|
53
|
+
path.join(
|
|
54
|
+
path.dirname(bundlePath),
|
|
55
|
+
// Strip the file extension
|
|
56
|
+
path.basename(bundlePath, path.extname(bundlePath))
|
|
57
|
+
) +
|
|
58
|
+
".bundle?" +
|
|
59
|
+
searchParams.toString();
|
|
44
60
|
}
|
|
45
61
|
return id;
|
|
46
62
|
}
|
|
@@ -24,6 +24,7 @@ export type Options = $ReadOnly<{
|
|
|
24
24
|
includeAsyncPaths: boolean,
|
|
25
25
|
projectRoot: string,
|
|
26
26
|
serverRoot: string,
|
|
27
|
+
sourceUrl: ?string,
|
|
27
28
|
...
|
|
28
29
|
}>;
|
|
29
30
|
|
|
@@ -48,16 +49,33 @@ function getModuleParams(module: Module<>, options: Options): Array<mixed> {
|
|
|
48
49
|
const id = options.createModuleId(dependency.absolutePath);
|
|
49
50
|
if (options.includeAsyncPaths && dependency.data.data.asyncType != null) {
|
|
50
51
|
hasPaths = true;
|
|
52
|
+
invariant(
|
|
53
|
+
options.sourceUrl != null,
|
|
54
|
+
'sourceUrl is required when includeAsyncPaths is true',
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// TODO: Only include path if the target is not in the bundle
|
|
58
|
+
|
|
59
|
+
// Construct a server-relative URL for the split bundle, propagating
|
|
60
|
+
// most parameters from the main bundle's URL.
|
|
61
|
+
|
|
62
|
+
const {searchParams} = new URL(options.sourceUrl);
|
|
63
|
+
searchParams.set('modulesOnly', 'true');
|
|
64
|
+
searchParams.set('runModule', 'false');
|
|
65
|
+
|
|
51
66
|
const bundlePath = path.relative(
|
|
52
67
|
options.serverRoot,
|
|
53
68
|
dependency.absolutePath,
|
|
54
69
|
);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
paths[id] =
|
|
71
|
+
'/' +
|
|
72
|
+
path.join(
|
|
73
|
+
path.dirname(bundlePath),
|
|
74
|
+
// Strip the file extension
|
|
75
|
+
path.basename(bundlePath, path.extname(bundlePath)),
|
|
76
|
+
) +
|
|
77
|
+
'.bundle?' +
|
|
78
|
+
searchParams.toString();
|
|
61
79
|
}
|
|
62
80
|
return id;
|
|
63
81
|
},
|
|
@@ -21,6 +21,7 @@ function processModules(
|
|
|
21
21
|
includeAsyncPaths,
|
|
22
22
|
projectRoot,
|
|
23
23
|
serverRoot,
|
|
24
|
+
sourceUrl,
|
|
24
25
|
}
|
|
25
26
|
) {
|
|
26
27
|
return [...modules]
|
|
@@ -34,6 +35,7 @@ function processModules(
|
|
|
34
35
|
includeAsyncPaths,
|
|
35
36
|
projectRoot,
|
|
36
37
|
serverRoot,
|
|
38
|
+
sourceUrl,
|
|
37
39
|
}),
|
|
38
40
|
]);
|
|
39
41
|
}
|
|
@@ -24,6 +24,7 @@ function processModules(
|
|
|
24
24
|
includeAsyncPaths,
|
|
25
25
|
projectRoot,
|
|
26
26
|
serverRoot,
|
|
27
|
+
sourceUrl,
|
|
27
28
|
}: $ReadOnly<{
|
|
28
29
|
filter?: (module: Module<>) => boolean,
|
|
29
30
|
createModuleId: string => number,
|
|
@@ -31,6 +32,7 @@ function processModules(
|
|
|
31
32
|
includeAsyncPaths: boolean,
|
|
32
33
|
projectRoot: string,
|
|
33
34
|
serverRoot: string,
|
|
35
|
+
sourceUrl: ?string,
|
|
34
36
|
}>,
|
|
35
37
|
): $ReadOnlyArray<[Module<>, string]> {
|
|
36
38
|
return [...modules]
|
|
@@ -44,6 +46,7 @@ function processModules(
|
|
|
44
46
|
includeAsyncPaths,
|
|
45
47
|
projectRoot,
|
|
46
48
|
serverRoot,
|
|
49
|
+
sourceUrl,
|
|
47
50
|
}),
|
|
48
51
|
]);
|
|
49
52
|
}
|
|
@@ -50,6 +50,7 @@ function generateModules(sourceModules, graph, options) {
|
|
|
50
50
|
function prepareModule(module, graph, options) {
|
|
51
51
|
const code = wrapModule(module, {
|
|
52
52
|
...options,
|
|
53
|
+
sourceUrl: url.format(options.clientUrl),
|
|
53
54
|
dev: true,
|
|
54
55
|
});
|
|
55
56
|
const inverseDependencies = getInverseDependencies(module.path, graph);
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* @oncall react_native
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {SourceLocation} from '@babel/code-frame';
|
|
12
11
|
import type {JsTransformOptions} from 'metro-transform-worker';
|
|
13
12
|
import type {RequireContextParams} from '../ModuleGraph/worker/collectDependencies';
|
|
14
13
|
import type {RequireContext} from '../lib/contextModule';
|
|
@@ -55,7 +54,10 @@ export interface TransformResultDependency {
|
|
|
55
54
|
*/
|
|
56
55
|
readonly isOptional?: boolean;
|
|
57
56
|
|
|
58
|
-
readonly locs: ReadonlyArray<
|
|
57
|
+
readonly locs: ReadonlyArray<{
|
|
58
|
+
readonly start: {readonly line: number; readonly column: number};
|
|
59
|
+
readonly end: {readonly line: number; readonly column: number};
|
|
60
|
+
}>;
|
|
59
61
|
|
|
60
62
|
/** Context for requiring a collection of modules. */
|
|
61
63
|
readonly contextParams?: RequireContextParams;
|
|
@@ -34,7 +34,7 @@ function createFunctionNameGetter(module) {
|
|
|
34
34
|
source: "dummy",
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
|
-
async function symbolicate(stack, maps, config) {
|
|
37
|
+
async function symbolicate(stack, maps, config, extraData) {
|
|
38
38
|
const mapsByUrl = new Map();
|
|
39
39
|
for (const [url, map] of maps) {
|
|
40
40
|
mapsByUrl.set(url, map);
|
|
@@ -108,7 +108,9 @@ async function symbolicate(stack, maps, config) {
|
|
|
108
108
|
function symbolicateFrame(frame) {
|
|
109
109
|
const module = findModule(frame);
|
|
110
110
|
if (!module) {
|
|
111
|
-
return
|
|
111
|
+
return {
|
|
112
|
+
...frame,
|
|
113
|
+
};
|
|
112
114
|
}
|
|
113
115
|
if (!Array.isArray(module.map)) {
|
|
114
116
|
throw new Error(
|
|
@@ -117,7 +119,9 @@ async function symbolicate(stack, maps, config) {
|
|
|
117
119
|
}
|
|
118
120
|
const originalPos = findOriginalPos(frame, module);
|
|
119
121
|
if (!originalPos) {
|
|
120
|
-
return
|
|
122
|
+
return {
|
|
123
|
+
...frame,
|
|
124
|
+
};
|
|
121
125
|
}
|
|
122
126
|
const methodName =
|
|
123
127
|
findFunctionName(originalPos, module) ?? frame.methodName;
|
|
@@ -129,15 +133,39 @@ async function symbolicate(stack, maps, config) {
|
|
|
129
133
|
column: originalPos.column0Based,
|
|
130
134
|
};
|
|
131
135
|
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* `customizeFrame` allows for custom modifications of the symbolicated frame in a stack.
|
|
139
|
+
* It can be used to collapse stack frames that are not relevant to users, pointing them
|
|
140
|
+
* to more relevant product code instead.
|
|
141
|
+
*
|
|
142
|
+
* An example usecase is a library throwing an error while sanitizing inputs from product code.
|
|
143
|
+
* In some cases, it's more useful to point the developer looking at the error towards the product code directly.
|
|
144
|
+
*/
|
|
132
145
|
async function customizeFrame(frame) {
|
|
133
146
|
const customizations =
|
|
134
147
|
(await config.symbolicator.customizeFrame(frame)) || {};
|
|
135
148
|
return {
|
|
136
149
|
...frame,
|
|
137
|
-
collapse: false,
|
|
138
150
|
...customizations,
|
|
139
151
|
};
|
|
140
152
|
}
|
|
141
|
-
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* `customizeStack` allows for custom modifications of a symbolicated stack.
|
|
156
|
+
* Where `customizeFrame` operates on individual frames, this hook can process the entire stack in context.
|
|
157
|
+
*
|
|
158
|
+
* Note: `customizeStack` has access to an `extraData` object which can be used to attach metadata
|
|
159
|
+
* to the error coming in, to be used by the customizeStack hook.
|
|
160
|
+
*/
|
|
161
|
+
async function customizeStack(symbolicatedStack) {
|
|
162
|
+
return await config.symbolicator.customizeStack(
|
|
163
|
+
symbolicatedStack,
|
|
164
|
+
extraData
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
return Promise.all(stack.map(symbolicateFrame).map(customizeFrame)).then(
|
|
168
|
+
customizeStack
|
|
169
|
+
);
|
|
142
170
|
}
|
|
143
171
|
module.exports = symbolicate;
|
|
@@ -30,9 +30,13 @@ export type StackFrameInput = {
|
|
|
30
30
|
+methodName: ?string,
|
|
31
31
|
...
|
|
32
32
|
};
|
|
33
|
-
export type
|
|
33
|
+
export type IntermediateStackFrame = {
|
|
34
34
|
...StackFrameInput,
|
|
35
|
-
|
|
35
|
+
collapse?: boolean,
|
|
36
|
+
...
|
|
37
|
+
};
|
|
38
|
+
export type StackFrameOutput = $ReadOnly<{
|
|
39
|
+
...IntermediateStackFrame,
|
|
36
40
|
...
|
|
37
41
|
}>;
|
|
38
42
|
type ExplodedSourceMapModule = $ElementType<ExplodedSourceMap, number>;
|
|
@@ -63,6 +67,7 @@ async function symbolicate(
|
|
|
63
67
|
stack: $ReadOnlyArray<StackFrameInput>,
|
|
64
68
|
maps: Iterable<[string, ExplodedSourceMap]>,
|
|
65
69
|
config: ConfigT,
|
|
70
|
+
extraData: mixed,
|
|
66
71
|
): Promise<$ReadOnlyArray<StackFrameOutput>> {
|
|
67
72
|
const mapsByUrl = new Map<?string, ExplodedSourceMap>();
|
|
68
73
|
for (const [url, map] of maps) {
|
|
@@ -157,10 +162,10 @@ async function symbolicate(
|
|
|
157
162
|
return null;
|
|
158
163
|
}
|
|
159
164
|
|
|
160
|
-
function symbolicateFrame(frame: StackFrameInput):
|
|
165
|
+
function symbolicateFrame(frame: StackFrameInput): IntermediateStackFrame {
|
|
161
166
|
const module = findModule(frame);
|
|
162
167
|
if (!module) {
|
|
163
|
-
return frame;
|
|
168
|
+
return {...frame};
|
|
164
169
|
}
|
|
165
170
|
if (!Array.isArray(module.map)) {
|
|
166
171
|
throw new Error(
|
|
@@ -169,7 +174,7 @@ async function symbolicate(
|
|
|
169
174
|
}
|
|
170
175
|
const originalPos = findOriginalPos(frame, module);
|
|
171
176
|
if (!originalPos) {
|
|
172
|
-
return frame;
|
|
177
|
+
return {...frame};
|
|
173
178
|
}
|
|
174
179
|
const methodName =
|
|
175
180
|
findFunctionName(originalPos, module) ?? frame.methodName;
|
|
@@ -182,15 +187,41 @@ async function symbolicate(
|
|
|
182
187
|
};
|
|
183
188
|
}
|
|
184
189
|
|
|
190
|
+
/**
|
|
191
|
+
* `customizeFrame` allows for custom modifications of the symbolicated frame in a stack.
|
|
192
|
+
* It can be used to collapse stack frames that are not relevant to users, pointing them
|
|
193
|
+
* to more relevant product code instead.
|
|
194
|
+
*
|
|
195
|
+
* An example usecase is a library throwing an error while sanitizing inputs from product code.
|
|
196
|
+
* In some cases, it's more useful to point the developer looking at the error towards the product code directly.
|
|
197
|
+
*/
|
|
185
198
|
async function customizeFrame(
|
|
186
|
-
frame:
|
|
187
|
-
): Promise<
|
|
199
|
+
frame: IntermediateStackFrame,
|
|
200
|
+
): Promise<IntermediateStackFrame> {
|
|
188
201
|
const customizations =
|
|
189
202
|
(await config.symbolicator.customizeFrame(frame)) || {};
|
|
190
|
-
return {...frame,
|
|
203
|
+
return {...frame, ...customizations};
|
|
191
204
|
}
|
|
192
205
|
|
|
193
|
-
|
|
206
|
+
/**
|
|
207
|
+
* `customizeStack` allows for custom modifications of a symbolicated stack.
|
|
208
|
+
* Where `customizeFrame` operates on individual frames, this hook can process the entire stack in context.
|
|
209
|
+
*
|
|
210
|
+
* Note: `customizeStack` has access to an `extraData` object which can be used to attach metadata
|
|
211
|
+
* to the error coming in, to be used by the customizeStack hook.
|
|
212
|
+
*/
|
|
213
|
+
async function customizeStack(
|
|
214
|
+
symbolicatedStack: Array<IntermediateStackFrame>,
|
|
215
|
+
): Promise<Array<IntermediateStackFrame>> {
|
|
216
|
+
return await config.symbolicator.customizeStack(
|
|
217
|
+
symbolicatedStack,
|
|
218
|
+
extraData,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return Promise.all(stack.map(symbolicateFrame).map(customizeFrame)).then(
|
|
223
|
+
customizeStack,
|
|
224
|
+
);
|
|
194
225
|
}
|
|
195
226
|
|
|
196
227
|
module.exports = symbolicate;
|
package/src/Server.js
CHANGED
|
@@ -884,7 +884,8 @@ class Server {
|
|
|
884
884
|
debug("Start symbolication");
|
|
885
885
|
/* $FlowFixMe: where is `rawBody` defined? Is it added by the `connect` framework? */
|
|
886
886
|
const body = await req.rawBody;
|
|
887
|
-
const
|
|
887
|
+
const parsedBody = JSON.parse(body);
|
|
888
|
+
const stack = parsedBody.stack.map((frame) => {
|
|
888
889
|
if (frame.file && frame.file.includes("://")) {
|
|
889
890
|
return {
|
|
890
891
|
...frame,
|
|
@@ -913,10 +914,11 @@ class Server {
|
|
|
913
914
|
Array.from(urls.values()).map(this._explodedSourceMapForURL, this)
|
|
914
915
|
);
|
|
915
916
|
debug("Performing fast symbolication");
|
|
916
|
-
const symbolicatedStack = await
|
|
917
|
+
const symbolicatedStack = await symbolicate(
|
|
917
918
|
stack,
|
|
918
919
|
zip(urls.values(), sourceMaps),
|
|
919
|
-
this._config
|
|
920
|
+
this._config,
|
|
921
|
+
parsedBody.extraData ?? {}
|
|
920
922
|
);
|
|
921
923
|
debug("Symbolication done");
|
|
922
924
|
res.end(
|
package/src/Server.js.flow
CHANGED
|
@@ -1094,7 +1094,8 @@ class Server {
|
|
|
1094
1094
|
debug('Start symbolication');
|
|
1095
1095
|
/* $FlowFixMe: where is `rawBody` defined? Is it added by the `connect` framework? */
|
|
1096
1096
|
const body = await req.rawBody;
|
|
1097
|
-
const
|
|
1097
|
+
const parsedBody = JSON.parse(body);
|
|
1098
|
+
const stack = parsedBody.stack.map(frame => {
|
|
1098
1099
|
if (frame.file && frame.file.includes('://')) {
|
|
1099
1100
|
return {
|
|
1100
1101
|
...frame,
|
|
@@ -1126,10 +1127,11 @@ class Server {
|
|
|
1126
1127
|
);
|
|
1127
1128
|
|
|
1128
1129
|
debug('Performing fast symbolication');
|
|
1129
|
-
const symbolicatedStack = await
|
|
1130
|
+
const symbolicatedStack = await symbolicate(
|
|
1130
1131
|
stack,
|
|
1131
1132
|
zip(urls.values(), sourceMaps),
|
|
1132
1133
|
this._config,
|
|
1134
|
+
parsedBody.extraData ?? {},
|
|
1133
1135
|
);
|
|
1134
1136
|
|
|
1135
1137
|
debug('Symbolication done');
|
package/src/index.d.ts
CHANGED
|
@@ -14,22 +14,25 @@ export * from './ModuleGraph/worker/collectDependencies';
|
|
|
14
14
|
export * from './Server';
|
|
15
15
|
export * from './lib/reporting';
|
|
16
16
|
|
|
17
|
-
import type {
|
|
17
|
+
import type {EventEmitter} from 'events';
|
|
18
|
+
import type {IncomingMessage, Server as HttpServer} from 'http';
|
|
18
19
|
import type {Server as HttpsServer} from 'https';
|
|
19
20
|
import type {
|
|
20
21
|
ConfigT,
|
|
21
22
|
InputConfigT,
|
|
22
|
-
loadConfig,
|
|
23
23
|
MetroConfig,
|
|
24
24
|
Middleware,
|
|
25
25
|
} from 'metro-config';
|
|
26
26
|
import type {CustomTransformOptions} from 'metro-babel-transformer';
|
|
27
27
|
import type {ReadOnlyGraph} from './DeltaBundler/types';
|
|
28
|
-
import type {
|
|
28
|
+
import type {Duplex} from 'stream';
|
|
29
29
|
import Yargs = require('yargs');
|
|
30
30
|
import type {default as MetroServer, ServerOptions} from './Server';
|
|
31
31
|
import type {OutputOptions, RequestOptions} from './shared/types';
|
|
32
32
|
|
|
33
|
+
export {loadConfig, mergeConfig, resolveConfig} from 'metro-config';
|
|
34
|
+
export {Terminal} from 'metro-core';
|
|
35
|
+
|
|
33
36
|
export {HttpServer, HttpsServer};
|
|
34
37
|
|
|
35
38
|
interface MetroMiddleWare {
|
|
@@ -43,6 +46,15 @@ export interface RunMetroOptions extends ServerOptions {
|
|
|
43
46
|
waitForBundler?: boolean;
|
|
44
47
|
}
|
|
45
48
|
|
|
49
|
+
interface WebsocketServer extends EventEmitter {
|
|
50
|
+
handleUpgrade<T = WebsocketServer>(
|
|
51
|
+
request: IncomingMessage,
|
|
52
|
+
socket: Duplex,
|
|
53
|
+
upgradeHead: Buffer,
|
|
54
|
+
callback: (client: T, request: IncomingMessage) => void,
|
|
55
|
+
): void;
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
export interface RunServerOptions {
|
|
47
59
|
hasReducedPerformance?: boolean;
|
|
48
60
|
host?: string;
|
|
@@ -63,7 +75,7 @@ export interface RunServerOptions {
|
|
|
63
75
|
waitForBundler?: boolean;
|
|
64
76
|
watch?: boolean;
|
|
65
77
|
websocketEndpoints?: {
|
|
66
|
-
[path: string]:
|
|
78
|
+
[path: string]: WebsocketServer;
|
|
67
79
|
};
|
|
68
80
|
}
|
|
69
81
|
|
|
@@ -114,8 +126,6 @@ export function runMetro(
|
|
|
114
126
|
options?: RunMetroOptions,
|
|
115
127
|
): Promise<MetroServer>;
|
|
116
128
|
|
|
117
|
-
export {loadConfig};
|
|
118
|
-
|
|
119
129
|
export function createConnectMiddleWare(
|
|
120
130
|
config: ConfigT,
|
|
121
131
|
options?: RunMetroOptions,
|
package/src/index.flow.js
CHANGED
|
@@ -23,11 +23,17 @@ const chalk = require("chalk");
|
|
|
23
23
|
const fs = require("fs");
|
|
24
24
|
const http = require("http");
|
|
25
25
|
const https = require("https");
|
|
26
|
-
const {
|
|
26
|
+
const {
|
|
27
|
+
getDefaultConfig,
|
|
28
|
+
loadConfig,
|
|
29
|
+
mergeConfig,
|
|
30
|
+
resolveConfig,
|
|
31
|
+
} = require("metro-config");
|
|
32
|
+
const { Terminal } = require("metro-core");
|
|
27
33
|
const { InspectorProxy } = require("metro-inspector-proxy");
|
|
28
34
|
const net = require("net");
|
|
29
35
|
const { parse } = require("url");
|
|
30
|
-
|
|
36
|
+
exports.Terminal = Terminal;
|
|
31
37
|
async function getConfig(config) {
|
|
32
38
|
const defaultConfig = await getDefaultConfig(config.projectRoot);
|
|
33
39
|
return mergeConfig(defaultConfig, config);
|
|
@@ -70,6 +76,7 @@ async function runMetro(config, options) {
|
|
|
70
76
|
exports.runMetro = runMetro;
|
|
71
77
|
exports.loadConfig = loadConfig;
|
|
72
78
|
exports.mergeConfig = mergeConfig;
|
|
79
|
+
exports.resolveConfig = resolveConfig;
|
|
73
80
|
const createConnectMiddleware = async function (config, options) {
|
|
74
81
|
const metroServer = await runMetro(config, options);
|
|
75
82
|
let enhancedMiddleware = metroServer.processRequest;
|
package/src/index.flow.js.flow
CHANGED
|
@@ -15,7 +15,8 @@ import type {CustomResolverOptions} from 'metro-resolver';
|
|
|
15
15
|
import type {ReadOnlyGraph} from './DeltaBundler';
|
|
16
16
|
import type {ServerOptions} from './Server';
|
|
17
17
|
import type {OutputOptions, RequestOptions} from './shared/types.flow.js';
|
|
18
|
-
import type
|
|
18
|
+
import type EventEmitter from 'events';
|
|
19
|
+
import type {IncomingMessage, Server as HttpServer} from 'http';
|
|
19
20
|
import type {Server as HttpsServer} from 'https';
|
|
20
21
|
import type {
|
|
21
22
|
ConfigT,
|
|
@@ -24,6 +25,7 @@ import type {
|
|
|
24
25
|
Middleware,
|
|
25
26
|
} from 'metro-config/src/configTypes.flow';
|
|
26
27
|
import type {CustomTransformOptions} from 'metro-transform-worker';
|
|
28
|
+
import type {Duplex} from 'stream';
|
|
27
29
|
import typeof Yargs from 'yargs';
|
|
28
30
|
|
|
29
31
|
const makeBuildCommand = require('./commands/build');
|
|
@@ -38,11 +40,16 @@ const chalk = require('chalk');
|
|
|
38
40
|
const fs = require('fs');
|
|
39
41
|
const http = require('http');
|
|
40
42
|
const https = require('https');
|
|
41
|
-
const {
|
|
43
|
+
const {
|
|
44
|
+
getDefaultConfig,
|
|
45
|
+
loadConfig,
|
|
46
|
+
mergeConfig,
|
|
47
|
+
resolveConfig,
|
|
48
|
+
} = require('metro-config');
|
|
49
|
+
const {Terminal} = require('metro-core');
|
|
42
50
|
const {InspectorProxy} = require('metro-inspector-proxy');
|
|
43
51
|
const net = require('net');
|
|
44
52
|
const {parse} = require('url');
|
|
45
|
-
const ws = require('ws');
|
|
46
53
|
|
|
47
54
|
type MetroMiddleWare = {
|
|
48
55
|
attachHmrServer: (httpServer: HttpServer | HttpsServer) => void,
|
|
@@ -56,6 +63,15 @@ export type RunMetroOptions = {
|
|
|
56
63
|
waitForBundler?: boolean,
|
|
57
64
|
};
|
|
58
65
|
|
|
66
|
+
interface WebsocketServer extends EventEmitter {
|
|
67
|
+
handleUpgrade<T = WebsocketServer>(
|
|
68
|
+
request: IncomingMessage,
|
|
69
|
+
socket: Duplex,
|
|
70
|
+
upgradeHead: Buffer,
|
|
71
|
+
callback: (client: T, request: IncomingMessage) => void,
|
|
72
|
+
): void;
|
|
73
|
+
}
|
|
74
|
+
|
|
59
75
|
export type RunServerOptions = $ReadOnly<{
|
|
60
76
|
hasReducedPerformance?: boolean,
|
|
61
77
|
host?: string,
|
|
@@ -69,7 +85,7 @@ export type RunServerOptions = $ReadOnly<{
|
|
|
69
85
|
waitForBundler?: boolean,
|
|
70
86
|
watch?: boolean,
|
|
71
87
|
websocketEndpoints?: $ReadOnly<{
|
|
72
|
-
[path: string]:
|
|
88
|
+
[path: string]: WebsocketServer,
|
|
73
89
|
}>,
|
|
74
90
|
}>;
|
|
75
91
|
|
|
@@ -121,6 +137,8 @@ export type RunBuildOptions = {
|
|
|
121
137
|
type BuildCommandOptions = {} | null;
|
|
122
138
|
type ServeCommandOptions = {} | null;
|
|
123
139
|
|
|
140
|
+
exports.Terminal = Terminal;
|
|
141
|
+
|
|
124
142
|
export type {MetroConfig};
|
|
125
143
|
|
|
126
144
|
async function getConfig(config: InputConfigT): Promise<ConfigT> {
|
|
@@ -174,6 +192,7 @@ async function runMetro(
|
|
|
174
192
|
exports.runMetro = runMetro;
|
|
175
193
|
exports.loadConfig = loadConfig;
|
|
176
194
|
exports.mergeConfig = mergeConfig;
|
|
195
|
+
exports.resolveConfig = resolveConfig;
|
|
177
196
|
|
|
178
197
|
const createConnectMiddleware = async function (
|
|
179
198
|
config: ConfigT,
|
|
@@ -105,8 +105,13 @@ class DependencyGraph extends EventEmitter {
|
|
|
105
105
|
_getClosestPackage(filePath) {
|
|
106
106
|
const parsedPath = path.parse(filePath);
|
|
107
107
|
const root = parsedPath.root;
|
|
108
|
-
let dir = parsedPath.dir;
|
|
108
|
+
let dir = path.join(parsedPath.dir, parsedPath.base);
|
|
109
109
|
do {
|
|
110
|
+
// If we've hit a node_modules directory, the closest package was not
|
|
111
|
+
// found (`filePath` was likely nonexistent).
|
|
112
|
+
if (path.basename(dir) === "node_modules") {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
110
115
|
const candidate = path.join(dir, "package.json");
|
|
111
116
|
if (this._fileSystem.exists(candidate)) {
|
|
112
117
|
return candidate;
|
|
@@ -152,8 +152,14 @@ class DependencyGraph extends EventEmitter {
|
|
|
152
152
|
_getClosestPackage(filePath: string): ?string {
|
|
153
153
|
const parsedPath = path.parse(filePath);
|
|
154
154
|
const root = parsedPath.root;
|
|
155
|
-
let dir = parsedPath.dir;
|
|
155
|
+
let dir = path.join(parsedPath.dir, parsedPath.base);
|
|
156
|
+
|
|
156
157
|
do {
|
|
158
|
+
// If we've hit a node_modules directory, the closest package was not
|
|
159
|
+
// found (`filePath` was likely nonexistent).
|
|
160
|
+
if (path.basename(dir) === 'node_modules') {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
157
163
|
const candidate = path.join(dir, 'package.json');
|
|
158
164
|
if (this._fileSystem.exists(candidate)) {
|
|
159
165
|
return candidate;
|