metro 0.76.7 → 0.78.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.
Files changed (52) hide show
  1. package/package.json +21 -23
  2. package/src/DeltaBundler/Graph.js +1 -1
  3. package/src/DeltaBundler/Graph.js.flow +1 -1
  4. package/src/DeltaBundler/Serializers/sourceMapGenerator.js.flow +0 -2
  5. package/src/DeltaBundler/WorkerFarm.js +4 -3
  6. package/src/DeltaBundler/WorkerFarm.js.flow +4 -3
  7. package/src/DeltaBundler/types.d.ts +2 -9
  8. package/src/DeltaBundler/types.flow.js.flow +4 -1
  9. package/src/HmrServer.js +9 -2
  10. package/src/HmrServer.js.flow +10 -3
  11. package/src/ModuleGraph/worker/collectDependencies.js +10 -2
  12. package/src/ModuleGraph/worker/collectDependencies.js.flow +12 -3
  13. package/src/Server/MultipartResponse.js +4 -0
  14. package/src/Server/MultipartResponse.js.flow +5 -0
  15. package/src/Server.js +43 -4
  16. package/src/Server.js.flow +42 -5
  17. package/src/commands/serve.js +1 -1
  18. package/src/commands/serve.js.flow +1 -1
  19. package/src/index.d.ts +0 -1
  20. package/src/index.flow.js +1 -18
  21. package/src/index.flow.js.flow +3 -32
  22. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-import.js +21 -0
  23. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-import.js.flow +17 -0
  24. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-multi-line-import-with-escapes.js +18 -0
  25. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-multi-line-import-with-escapes.js.flow +29 -0
  26. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-multi-line-import.js +18 -0
  27. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-multi-line-import.js.flow +29 -0
  28. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-require-with-embedded-comment.js +18 -0
  29. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-require-with-embedded-comment.js.flow +17 -0
  30. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-require.js +17 -0
  31. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-require.js.flow +17 -0
  32. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-specifier-with-escapes.js +20 -0
  33. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-specifier-with-escapes.js.flow +19 -0
  34. package/src/integration_tests/basic_bundle/build-errors/inline-requires-cannot-resolve-import.js +21 -0
  35. package/src/integration_tests/basic_bundle/build-errors/inline-requires-cannot-resolve-import.js.flow +17 -0
  36. package/src/integration_tests/basic_bundle/build-errors/inline-requires-cannot-resolve-require.js +17 -0
  37. package/src/integration_tests/basic_bundle/build-errors/inline-requires-cannot-resolve-require.js.flow +17 -0
  38. package/src/integration_tests/metro.config.js +5 -3
  39. package/src/lib/contextModule.js +1 -1
  40. package/src/lib/contextModule.js.flow +1 -1
  41. package/src/lib/createWebsocketServer.js +2 -0
  42. package/src/lib/createWebsocketServer.js.flow +5 -2
  43. package/src/lib/transformHelpers.js +9 -8
  44. package/src/lib/transformHelpers.js.flow +13 -9
  45. package/src/node-haste/DependencyGraph/ModuleResolution.js +139 -52
  46. package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +152 -51
  47. package/src/node-haste/DependencyGraph/{createHasteMap.js → createFileMap.js} +21 -6
  48. package/src/node-haste/DependencyGraph/{createHasteMap.js.flow → createFileMap.js.flow} +17 -5
  49. package/src/node-haste/DependencyGraph.d.ts +5 -2
  50. package/src/node-haste/DependencyGraph.js +32 -27
  51. package/src/node-haste/DependencyGraph.js.flow +25 -15
  52. package/src/node-haste/Package.js.flow +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metro",
3
- "version": "0.76.7",
3
+ "version": "0.78.0",
4
4
  "description": "🚇 The JavaScript bundler for React Native.",
5
5
  "main": "src/index.js",
6
6
  "bin": "src/cli.js",
@@ -29,28 +29,25 @@
29
29
  "denodeify": "^1.2.1",
30
30
  "error-stack-parser": "^2.0.6",
31
31
  "graceful-fs": "^4.2.4",
32
- "hermes-parser": "0.12.0",
32
+ "hermes-parser": "0.15.0",
33
33
  "image-size": "^1.0.2",
34
34
  "invariant": "^2.2.4",
35
35
  "jest-worker": "^27.2.0",
36
36
  "jsc-safe-url": "^0.2.2",
37
37
  "lodash.throttle": "^4.1.1",
38
- "metro-babel-transformer": "0.76.7",
39
- "metro-cache": "0.76.7",
40
- "metro-cache-key": "0.76.7",
41
- "metro-config": "0.76.7",
42
- "metro-core": "0.76.7",
43
- "metro-file-map": "0.76.7",
44
- "metro-inspector-proxy": "0.76.7",
45
- "metro-minify-terser": "0.76.7",
46
- "metro-minify-uglify": "0.76.7",
47
- "metro-react-native-babel-preset": "0.76.7",
48
- "metro-resolver": "0.76.7",
49
- "metro-runtime": "0.76.7",
50
- "metro-source-map": "0.76.7",
51
- "metro-symbolicate": "0.76.7",
52
- "metro-transform-plugins": "0.76.7",
53
- "metro-transform-worker": "0.76.7",
38
+ "metro-babel-transformer": "0.78.0",
39
+ "metro-cache": "0.78.0",
40
+ "metro-cache-key": "0.78.0",
41
+ "metro-config": "0.78.0",
42
+ "metro-core": "0.78.0",
43
+ "metro-file-map": "0.78.0",
44
+ "metro-minify-terser": "0.78.0",
45
+ "metro-resolver": "0.78.0",
46
+ "metro-runtime": "0.78.0",
47
+ "metro-source-map": "0.78.0",
48
+ "metro-symbolicate": "0.78.0",
49
+ "metro-transform-plugins": "0.78.0",
50
+ "metro-transform-worker": "0.78.0",
54
51
  "mime-types": "^2.1.27",
55
52
  "node-fetch": "^2.2.0",
56
53
  "nullthrows": "^1.1.1",
@@ -64,20 +61,21 @@
64
61
  },
65
62
  "devDependencies": {
66
63
  "@babel/plugin-transform-flow-strip-types": "^7.20.0",
64
+ "@babel/plugin-transform-modules-commonjs": "^7.0.0",
65
+ "@react-native/babel-preset": "0.73.16",
66
+ "@react-native/metro-babel-transformer": "0.73.11",
67
67
  "babel-jest": "^29.2.1",
68
68
  "dedent": "^0.7.0",
69
69
  "jest-snapshot": "^26.5.2",
70
70
  "jest-snapshot-serializer-raw": "^1.2.0",
71
- "metro-babel-register": "0.76.7",
72
- "metro-memory-fs": "0.76.7",
73
- "metro-react-native-babel-preset": "0.76.7",
74
- "metro-react-native-babel-transformer": "0.76.7",
71
+ "metro-babel-register": "0.78.0",
72
+ "metro-memory-fs": "0.78.0",
75
73
  "mock-req": "^0.2.0",
76
74
  "mock-res": "^0.6.0",
77
75
  "stack-trace": "^0.0.10"
78
76
  },
79
77
  "license": "MIT",
80
78
  "engines": {
81
- "node": ">=16"
79
+ "node": ">=18"
82
80
  }
83
81
  }
@@ -470,7 +470,7 @@ class Graph {
470
470
  } else {
471
471
  try {
472
472
  resolvedDep = {
473
- absolutePath: options.resolve(parentPath, dep.name).filePath,
473
+ absolutePath: options.resolve(parentPath, dep).filePath,
474
474
  data: dep,
475
475
  };
476
476
 
@@ -574,7 +574,7 @@ export class Graph<T = MixedOutput> {
574
574
  } else {
575
575
  try {
576
576
  resolvedDep = {
577
- absolutePath: options.resolve(parentPath, dep.name).filePath,
577
+ absolutePath: options.resolve(parentPath, dep).filePath,
578
578
  data: dep,
579
579
  };
580
580
 
@@ -26,8 +26,6 @@ const {
26
26
  fromRawMappingsNonBlocking,
27
27
  } = require('metro-source-map');
28
28
 
29
- type ReturnType<F> = $Call<<A, R>((...A) => R) => R, F>;
30
-
31
29
  function getSourceMapInfosImpl(
32
30
  isBlocking: boolean,
33
31
  onDone: ($ReadOnlyArray<ReturnType<typeof getSourceMapInfo>>) => void,
@@ -17,9 +17,10 @@ class WorkerFarm {
17
17
  constructor(config, transformerConfig) {
18
18
  this._config = config;
19
19
  this._transformerConfig = transformerConfig;
20
+ const absoluteWorkerPath = require.resolve(config.transformer.workerPath);
20
21
  if (this._config.maxWorkers > 1) {
21
22
  const worker = this._makeFarm(
22
- this._config.transformer.workerPath,
23
+ absoluteWorkerPath,
23
24
  ["transform"],
24
25
  this._config.maxWorkers
25
26
  );
@@ -69,13 +70,13 @@ class WorkerFarm {
69
70
  }
70
71
  }
71
72
  }
72
- _makeFarm(workerPath, exposedMethods, numWorkers) {
73
+ _makeFarm(absoluteWorkerPath, exposedMethods, numWorkers) {
73
74
  const env = {
74
75
  ...process.env,
75
76
  // Force color to print syntax highlighted code frames.
76
77
  FORCE_COLOR: 1,
77
78
  };
78
- return new JestWorker(workerPath, {
79
+ return new JestWorker(absoluteWorkerPath, {
79
80
  computeWorkerKey: this._config.stickyWorkers
80
81
  ? // $FlowFixMe[method-unbinding] added when improving typing for this parameters
81
82
  // $FlowFixMe[incompatible-call]
@@ -39,10 +39,11 @@ class WorkerFarm {
39
39
  constructor(config: ConfigT, transformerConfig: TransformerConfig) {
40
40
  this._config = config;
41
41
  this._transformerConfig = transformerConfig;
42
+ const absoluteWorkerPath = require.resolve(config.transformer.workerPath);
42
43
 
43
44
  if (this._config.maxWorkers > 1) {
44
45
  const worker = this._makeFarm(
45
- this._config.transformer.workerPath,
46
+ absoluteWorkerPath,
46
47
  ['transform'],
47
48
  this._config.maxWorkers,
48
49
  );
@@ -107,7 +108,7 @@ class WorkerFarm {
107
108
  }
108
109
 
109
110
  _makeFarm(
110
- workerPath: string,
111
+ absoluteWorkerPath: string,
111
112
  exposedMethods: $ReadOnlyArray<string>,
112
113
  numWorkers: number,
113
114
  ): any {
@@ -117,7 +118,7 @@ class WorkerFarm {
117
118
  FORCE_COLOR: 1,
118
119
  };
119
120
 
120
- return new JestWorker(workerPath, {
121
+ return new JestWorker(absoluteWorkerPath, {
121
122
  computeWorkerKey: this._config.stickyWorkers
122
123
  ? // $FlowFixMe[method-unbinding] added when improving typing for this parameters
123
124
  // $FlowFixMe[incompatible-call]
@@ -19,7 +19,7 @@ export interface MixedOutput {
19
19
  readonly type: string;
20
20
  }
21
21
 
22
- export type AsyncDependencyType = 'async' | 'prefetch';
22
+ export type AsyncDependencyType = 'async' | 'prefetch' | 'weak';
23
23
 
24
24
  export interface TransformResultDependency {
25
25
  /**
@@ -42,13 +42,6 @@ export interface TransformResultDependency {
42
42
  */
43
43
  readonly asyncType: AsyncDependencyType | null;
44
44
 
45
- /**
46
- * The condition for splitting on this dependency edge.
47
- */
48
- readonly splitCondition?: {
49
- readonly mobileConfigName: string;
50
- };
51
-
52
45
  /**
53
46
  * The dependency is enclosed in a try/catch block.
54
47
  */
@@ -133,7 +126,7 @@ export interface BundlerResolution {
133
126
  }
134
127
 
135
128
  export interface Options<T = MixedOutput> {
136
- readonly resolve: (from: string, to: string) => string;
129
+ readonly resolve: (from: string, to: TransformResultDependency) => string;
137
130
  readonly transform: TransformFn<T>;
138
131
  readonly transformOptions: TransformInputOptions;
139
132
  readonly onProgress:
@@ -128,7 +128,10 @@ export type BundlerResolution = $ReadOnly<{
128
128
  }>;
129
129
 
130
130
  export type Options<T = MixedOutput> = {
131
- +resolve: (from: string, to: string) => BundlerResolution,
131
+ +resolve: (
132
+ from: string,
133
+ dependency: TransformResultDependency,
134
+ ) => BundlerResolution,
132
135
  +transform: TransformFn<T>,
133
136
  +transformOptions: TransformInputOptions,
134
137
  +onProgress: ?(numProcessed: number, total: number) => mixed,
package/src/HmrServer.js CHANGED
@@ -74,7 +74,14 @@ class HmrServer {
74
74
  const resolvedEntryFilePath = resolutionFn(
75
75
  (this._config.server.unstable_serverRoot ?? this._config.projectRoot) +
76
76
  "/.",
77
- entryFile
77
+ {
78
+ name: entryFile,
79
+ data: {
80
+ key: entryFile,
81
+ asyncType: null,
82
+ locs: [],
83
+ },
84
+ }
78
85
  ).filePath;
79
86
  const graphId = getGraphId(resolvedEntryFilePath, transformOptions, {
80
87
  resolverOptions,
@@ -151,7 +158,7 @@ class HmrServer {
151
158
  onClientMessage = async (client, message, sendFn) => {
152
159
  let data;
153
160
  try {
154
- data = JSON.parse(message);
161
+ data = JSON.parse(String(message));
155
162
  } catch (error) {
156
163
  send([sendFn], {
157
164
  type: "error",
@@ -120,7 +120,14 @@ class HmrServer<TClient: Client> {
120
120
  const resolvedEntryFilePath = resolutionFn(
121
121
  (this._config.server.unstable_serverRoot ?? this._config.projectRoot) +
122
122
  '/.',
123
- entryFile,
123
+ {
124
+ name: entryFile,
125
+ data: {
126
+ key: entryFile,
127
+ asyncType: null,
128
+ locs: [],
129
+ },
130
+ },
124
131
  ).filePath;
125
132
  const graphId = getGraphId(resolvedEntryFilePath, transformOptions, {
126
133
  resolverOptions,
@@ -199,12 +206,12 @@ class HmrServer<TClient: Client> {
199
206
 
200
207
  onClientMessage: (
201
208
  client: TClient,
202
- message: string,
209
+ message: string | Buffer | ArrayBuffer | Array<Buffer>,
203
210
  sendFn: (data: string) => void,
204
211
  ) => Promise<void> = async (client, message, sendFn) => {
205
212
  let data: HmrClientMessage;
206
213
  try {
207
- data = JSON.parse(message);
214
+ data = JSON.parse(String(message));
208
215
  } catch (error) {
209
216
  send([sendFn], {
210
217
  type: 'error',
@@ -336,10 +336,18 @@ function processRequireCall(path, state) {
336
336
  }
337
337
  function getNearestLocFromPath(path) {
338
338
  let current = path;
339
- while (current && !current.node.loc) {
339
+ while (
340
+ current &&
341
+ !current.node.loc &&
342
+ // $FlowIgnore[prop-missing] METRO_INLINE_REQUIRES_INIT_LOC is Metro-specific and not typed
343
+ !current.node.METRO_INLINE_REQUIRES_INIT_LOC
344
+ ) {
340
345
  current = current.parentPath;
341
346
  }
342
- return current?.node.loc;
347
+ return (
348
+ // $FlowIgnore[prop-missing] METRO_INLINE_REQUIRES_INIT_LOC is Metro-specific and not typed
349
+ current?.node.METRO_INLINE_REQUIRES_INIT_LOC ?? current?.node.loc
350
+ );
343
351
  }
344
352
  function registerDependency(state, qualifier, path) {
345
353
  const dependency = state.dependencyRegistry.registerDependency(qualifier);
@@ -56,13 +56,14 @@ type DependencyData = $ReadOnly<{
56
56
  // (ex. `require('foo')`)
57
57
  asyncType: AsyncDependencyType | null,
58
58
  isOptional?: boolean,
59
- locs: Array<BabelSourceLocation>,
59
+ locs: $ReadOnlyArray<BabelSourceLocation>,
60
60
  /** Context for requiring a collection of modules. */
61
61
  contextParams?: RequireContextParams,
62
62
  }>;
63
63
 
64
64
  export type MutableInternalDependency = {
65
65
  ...DependencyData,
66
+ locs: Array<BabelSourceLocation>,
66
67
  index: number,
67
68
  name: string,
68
69
  };
@@ -494,10 +495,18 @@ function processRequireCall(
494
495
 
495
496
  function getNearestLocFromPath(path: NodePath<>): ?BabelSourceLocation {
496
497
  let current: ?(NodePath<> | NodePath<BabelNode>) = path;
497
- while (current && !current.node.loc) {
498
+ while (
499
+ current &&
500
+ !current.node.loc &&
501
+ // $FlowIgnore[prop-missing] METRO_INLINE_REQUIRES_INIT_LOC is Metro-specific and not typed
502
+ !current.node.METRO_INLINE_REQUIRES_INIT_LOC
503
+ ) {
498
504
  current = current.parentPath;
499
505
  }
500
- return current?.node.loc;
506
+ return (
507
+ // $FlowIgnore[prop-missing] METRO_INLINE_REQUIRES_INIT_LOC is Metro-specific and not typed
508
+ current?.node.METRO_INLINE_REQUIRES_INIT_LOC ?? current?.node.loc
509
+ );
501
510
  }
502
511
 
503
512
  export type ImportQualifier = $ReadOnly<{
@@ -69,5 +69,9 @@ class MultipartResponse {
69
69
  this.writeChunk(this.headers, data, true);
70
70
  this.res.end();
71
71
  }
72
+ once(name, fn) {
73
+ this.res.once(name, fn);
74
+ return this;
75
+ }
72
76
  }
73
77
  module.exports = MultipartResponse;
@@ -93,6 +93,11 @@ class MultipartResponse {
93
93
  this.writeChunk(this.headers, data, true);
94
94
  this.res.end();
95
95
  }
96
+
97
+ once(name: string, fn: () => mixed): this {
98
+ this.res.once(name, fn);
99
+ return this;
100
+ }
96
101
  }
97
102
 
98
103
  module.exports = MultipartResponse;
package/src/Server.js CHANGED
@@ -32,6 +32,7 @@ const parsePlatformFilePath = require("./node-haste/lib/parsePlatformFilePath");
32
32
  const symbolicate = require("./Server/symbolicate");
33
33
  const { codeFrameColumns } = require("@babel/code-frame");
34
34
  const MultipartResponse = require("./Server/MultipartResponse");
35
+ const { performance } = require("perf_hooks");
35
36
  const debug = require("debug")("Metro:Server");
36
37
  const fs = require("graceful-fs");
37
38
  const invariant = require("invariant");
@@ -433,6 +434,7 @@ class Server {
433
434
  bundleOptions,
434
435
  buildContext
435
436
  ) {
437
+ const requestStartTimestamp = performance.timeOrigin + performance.now();
436
438
  const { buildNumber } = buildContext;
437
439
  const {
438
440
  entryFile,
@@ -550,6 +552,7 @@ class Server {
550
552
  serializerOptions,
551
553
  transformOptions,
552
554
  bundlePerfLogger: buildContext.bundlePerfLogger,
555
+ requestStartTimestamp,
553
556
  };
554
557
  const logEntry = log(
555
558
  createActionStartEntry(createStartEntry(startContext))
@@ -632,8 +635,11 @@ class Server {
632
635
  serializerOptions,
633
636
  transformOptions,
634
637
  bundlePerfLogger,
638
+ requestStartTimestamp,
635
639
  }) => {
636
- bundlePerfLogger.start();
640
+ bundlePerfLogger.start({
641
+ timestamp: requestStartTimestamp,
642
+ });
637
643
  bundlePerfLogger.annotate({
638
644
  string: {
639
645
  bundle_url: entryFile,
@@ -658,6 +664,11 @@ class Server {
658
664
  lazy: graphOptions.lazy,
659
665
  }
660
666
  ));
667
+ bundlePerfLogger.annotate({
668
+ int: {
669
+ graph_node_count: revision.graph.dependencies.size,
670
+ },
671
+ });
661
672
  bundlePerfLogger.point("resolvingAndTransformingDependencies_end");
662
673
  bundlePerfLogger.point("serializingBundle_start");
663
674
  const serializer =
@@ -701,7 +712,6 @@ class Server {
701
712
  );
702
713
  bundlePerfLogger.point("serializingBundle_end");
703
714
  const bundleCode = typeof bundle === "string" ? bundle : bundle.code;
704
- bundlePerfLogger.end("SUCCESS");
705
715
  return {
706
716
  numModifiedFiles: delta.reset
707
717
  ? delta.added.size + revision.prepend.length
@@ -711,7 +721,19 @@ class Server {
711
721
  bundle: bundleCode,
712
722
  };
713
723
  },
714
- finish({ req, mres, serializerOptions, result }) {
724
+ finish({ req, mres, serializerOptions, result, bundlePerfLogger }) {
725
+ bundlePerfLogger.annotate({
726
+ int: {
727
+ bundle_length: result.bundle.length,
728
+ bundle_byte_length: Buffer.byteLength(result.bundle),
729
+ },
730
+ });
731
+ mres.once("error", () => {
732
+ bundlePerfLogger.end("FAIL");
733
+ });
734
+ mres.once("finish", () => {
735
+ bundlePerfLogger.end("SUCCESS");
736
+ });
715
737
  if (
716
738
  // We avoid parsing the dates since the client should never send a more
717
739
  // recent date than the one returned by the Delta Bundler (if that's the
@@ -719,10 +741,20 @@ class Server {
719
741
  req.headers["if-modified-since"] ===
720
742
  result.lastModifiedDate.toUTCString()
721
743
  ) {
744
+ bundlePerfLogger.annotate({
745
+ string: {
746
+ http_status: "304",
747
+ },
748
+ });
722
749
  debug("Responding with 304");
723
750
  mres.writeHead(304);
724
751
  mres.end();
725
752
  } else {
753
+ bundlePerfLogger.annotate({
754
+ string: {
755
+ http_status: "200",
756
+ },
757
+ });
726
758
  mres.setHeader(
727
759
  FILES_CHANGED_COUNT_HEADER,
728
760
  String(result.numModifiedFiles)
@@ -1042,7 +1074,14 @@ class Server {
1042
1074
  relativeTo === "server"
1043
1075
  ? this._getServerRootDir()
1044
1076
  : this._config.projectRoot;
1045
- return resolutionFn(`${rootDir}/.`, filePath).filePath;
1077
+ return resolutionFn(`${rootDir}/.`, {
1078
+ name: filePath,
1079
+ data: {
1080
+ key: filePath,
1081
+ locs: [],
1082
+ asyncType: null,
1083
+ },
1084
+ }).filePath;
1046
1085
  }
1047
1086
  getNewBuildNumber() {
1048
1087
  return this._nextBundleBuildNumber++;
@@ -64,6 +64,7 @@ const parsePlatformFilePath = require('./node-haste/lib/parsePlatformFilePath');
64
64
  const symbolicate = require('./Server/symbolicate');
65
65
  const {codeFrameColumns} = require('@babel/code-frame');
66
66
  const MultipartResponse = require('./Server/MultipartResponse');
67
+ const {performance} = require('perf_hooks');
67
68
  const debug = require('debug')('Metro:Server');
68
69
  const fs = require('graceful-fs');
69
70
  const invariant = require('invariant');
@@ -106,6 +107,7 @@ type ProcessStartContext = {
106
107
  +req: IncomingMessage,
107
108
  +revisionId?: ?RevisionId,
108
109
  +bundlePerfLogger: RootPerfLogger,
110
+ +requestStartTimestamp: number,
109
111
  ...SplitBundleOptions,
110
112
  };
111
113
 
@@ -595,6 +597,7 @@ class Server {
595
597
  bundlePerfLogger: RootPerfLogger,
596
598
  }>,
597
599
  ): Promise<void> {
600
+ const requestStartTimestamp = performance.timeOrigin + performance.now();
598
601
  const {buildNumber} = buildContext;
599
602
  const {
600
603
  entryFile,
@@ -717,6 +720,7 @@ class Server {
717
720
  serializerOptions,
718
721
  transformOptions,
719
722
  bundlePerfLogger: buildContext.bundlePerfLogger,
723
+ requestStartTimestamp,
720
724
  };
721
725
  const logEntry = log(
722
726
  createActionStartEntry(createStartEntry(startContext)),
@@ -823,8 +827,11 @@ class Server {
823
827
  serializerOptions,
824
828
  transformOptions,
825
829
  bundlePerfLogger,
830
+ requestStartTimestamp,
826
831
  }) => {
827
- bundlePerfLogger.start();
832
+ bundlePerfLogger.start({
833
+ timestamp: requestStartTimestamp,
834
+ });
828
835
  bundlePerfLogger.annotate({
829
836
  string: {
830
837
  bundle_url: entryFile,
@@ -850,6 +857,13 @@ class Server {
850
857
  lazy: graphOptions.lazy,
851
858
  },
852
859
  ));
860
+
861
+ bundlePerfLogger.annotate({
862
+ int: {
863
+ graph_node_count: revision.graph.dependencies.size,
864
+ },
865
+ });
866
+
853
867
  bundlePerfLogger.point('resolvingAndTransformingDependencies_end');
854
868
  bundlePerfLogger.point('serializingBundle_start');
855
869
  const serializer =
@@ -896,8 +910,6 @@ class Server {
896
910
 
897
911
  const bundleCode = typeof bundle === 'string' ? bundle : bundle.code;
898
912
 
899
- bundlePerfLogger.end('SUCCESS');
900
-
901
913
  return {
902
914
  numModifiedFiles: delta.reset
903
915
  ? delta.added.size + revision.prepend.length
@@ -907,7 +919,19 @@ class Server {
907
919
  bundle: bundleCode,
908
920
  };
909
921
  },
910
- finish({req, mres, serializerOptions, result}) {
922
+ finish({req, mres, serializerOptions, result, bundlePerfLogger}) {
923
+ bundlePerfLogger.annotate({
924
+ int: {
925
+ bundle_length: result.bundle.length,
926
+ bundle_byte_length: Buffer.byteLength(result.bundle),
927
+ },
928
+ });
929
+ mres.once('error', () => {
930
+ bundlePerfLogger.end('FAIL');
931
+ });
932
+ mres.once('finish', () => {
933
+ bundlePerfLogger.end('SUCCESS');
934
+ });
911
935
  if (
912
936
  // We avoid parsing the dates since the client should never send a more
913
937
  // recent date than the one returned by the Delta Bundler (if that's the
@@ -915,10 +939,20 @@ class Server {
915
939
  req.headers['if-modified-since'] ===
916
940
  result.lastModifiedDate.toUTCString()
917
941
  ) {
942
+ bundlePerfLogger.annotate({
943
+ string: {
944
+ http_status: '304',
945
+ },
946
+ });
918
947
  debug('Responding with 304');
919
948
  mres.writeHead(304);
920
949
  mres.end();
921
950
  } else {
951
+ bundlePerfLogger.annotate({
952
+ string: {
953
+ http_status: '200',
954
+ },
955
+ });
922
956
  mres.setHeader(
923
957
  FILES_CHANGED_COUNT_HEADER,
924
958
  String(result.numModifiedFiles),
@@ -1276,7 +1310,10 @@ class Server {
1276
1310
  relativeTo === 'server'
1277
1311
  ? this._getServerRootDir()
1278
1312
  : this._config.projectRoot;
1279
- return resolutionFn(`${rootDir}/.`, filePath).filePath;
1313
+ return resolutionFn(`${rootDir}/.`, {
1314
+ name: filePath,
1315
+ data: {key: filePath, locs: [], asyncType: null},
1316
+ }).filePath;
1280
1317
  }
1281
1318
 
1282
1319
  getNewBuildNumber(): number {
@@ -32,7 +32,7 @@ module.exports = () => ({
32
32
  yargs.option("port", {
33
33
  alias: "p",
34
34
  type: "number",
35
- default: 8080,
35
+ default: 8081,
36
36
  });
37
37
  yargs.option("max-workers", {
38
38
  alias: "j",
@@ -48,7 +48,7 @@ module.exports = (): {
48
48
  });
49
49
 
50
50
  yargs.option('host', {alias: 'h', type: 'string', default: 'localhost'});
51
- yargs.option('port', {alias: 'p', type: 'number', default: 8080});
51
+ yargs.option('port', {alias: 'p', type: 'number', default: 8081});
52
52
 
53
53
  yargs.option('max-workers', {alias: 'j', type: 'number'});
54
54
 
package/src/index.d.ts CHANGED
@@ -62,7 +62,6 @@ export interface RunServerOptions {
62
62
  host?: string;
63
63
  onError?: (error: Error & {code?: string}) => void;
64
64
  onReady?: (server: HttpServer | HttpsServer) => void;
65
- runInspectorProxy?: boolean;
66
65
  secureServerOptions?: Record<string, unknown>;
67
66
 
68
67
  /** @deprecated since version 0.61 */
package/src/index.flow.js CHANGED
@@ -31,7 +31,6 @@ const {
31
31
  resolveConfig,
32
32
  } = require("metro-config");
33
33
  const { Terminal } = require("metro-core");
34
- const { InspectorProxy } = require("metro-inspector-proxy");
35
34
  const net = require("net");
36
35
  const { parse } = require("url");
37
36
  exports.Terminal = Terminal;
@@ -140,7 +139,7 @@ exports.runServer = async (
140
139
  waitForBundler = false,
141
140
  websocketEndpoints = {},
142
141
  watch,
143
- }
142
+ } = {}
144
143
  ) => {
145
144
  await earlyPortCheck(host, config.server.port);
146
145
  if (secure != null || secureCert != null || secureKey != null) {
@@ -167,10 +166,6 @@ exports.runServer = async (
167
166
  for (const handler of unstable_extraMiddleware ?? []) {
168
167
  serverApp.use(handler);
169
168
  }
170
- let inspectorProxy = null;
171
- if (config.server.runInspectorProxy) {
172
- inspectorProxy = new InspectorProxy(config.projectRoot);
173
- }
174
169
  let httpServer;
175
170
  if (secure || secureServerOptions != null) {
176
171
  let options = secureServerOptions;
@@ -200,11 +195,6 @@ exports.runServer = async (
200
195
  }
201
196
  websocketEndpoints = {
202
197
  ...websocketEndpoints,
203
- ...(inspectorProxy
204
- ? {
205
- ...inspectorProxy.createWebSocketListeners(httpServer),
206
- }
207
- : {}),
208
198
  "/hot": createWebsocketServer({
209
199
  websocketServer: new MetroHmrServer(
210
200
  metroServer.getBundler(),
@@ -228,13 +218,6 @@ exports.runServer = async (
228
218
  socket.destroy();
229
219
  }
230
220
  });
231
- if (inspectorProxy) {
232
- // TODO(hypuk): Refactor inspectorProxy.processRequest into separate request handlers
233
- // so that we could provide routes (/json/list and /json/version) here.
234
- // Currently this causes Metro to give warning about T31407894.
235
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
236
- serverApp.use(inspectorProxy.processRequest.bind(inspectorProxy));
237
- }
238
221
  resolve(httpServer);
239
222
  });
240
223