metro 0.81.0-alpha.1 → 0.81.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metro",
3
- "version": "0.81.0-alpha.1",
3
+ "version": "0.81.0",
4
4
  "description": "🚇 The JavaScript bundler for React Native.",
5
5
  "main": "src/index.js",
6
6
  "bin": "src/cli.js",
@@ -29,24 +29,24 @@
29
29
  "error-stack-parser": "^2.0.6",
30
30
  "flow-enums-runtime": "^0.0.6",
31
31
  "graceful-fs": "^4.2.4",
32
- "hermes-parser": "0.23.1",
32
+ "hermes-parser": "0.24.0",
33
33
  "image-size": "^1.0.2",
34
34
  "invariant": "^2.2.4",
35
35
  "jest-worker": "^29.6.3",
36
36
  "jsc-safe-url": "^0.2.2",
37
37
  "lodash.throttle": "^4.1.1",
38
- "metro-babel-transformer": "0.81.0-alpha.1",
39
- "metro-cache": "0.81.0-alpha.1",
40
- "metro-cache-key": "0.81.0-alpha.1",
41
- "metro-config": "0.81.0-alpha.1",
42
- "metro-core": "0.81.0-alpha.1",
43
- "metro-file-map": "0.81.0-alpha.1",
44
- "metro-resolver": "0.81.0-alpha.1",
45
- "metro-runtime": "0.81.0-alpha.1",
46
- "metro-source-map": "0.81.0-alpha.1",
47
- "metro-symbolicate": "0.81.0-alpha.1",
48
- "metro-transform-plugins": "0.81.0-alpha.1",
49
- "metro-transform-worker": "0.81.0-alpha.1",
38
+ "metro-babel-transformer": "0.81.0",
39
+ "metro-cache": "0.81.0",
40
+ "metro-cache-key": "0.81.0",
41
+ "metro-config": "0.81.0",
42
+ "metro-core": "0.81.0",
43
+ "metro-file-map": "0.81.0",
44
+ "metro-resolver": "0.81.0",
45
+ "metro-runtime": "0.81.0",
46
+ "metro-source-map": "0.81.0",
47
+ "metro-symbolicate": "0.81.0",
48
+ "metro-transform-plugins": "0.81.0",
49
+ "metro-transform-worker": "0.81.0",
50
50
  "mime-types": "^2.1.27",
51
51
  "nullthrows": "^1.1.1",
52
52
  "serialize-error": "^2.1.0",
@@ -65,8 +65,8 @@
65
65
  "dedent": "^0.7.0",
66
66
  "jest-snapshot": "^29.6.3",
67
67
  "jest-snapshot-serializer-raw": "^1.2.0",
68
- "metro-babel-register": "0.81.0-alpha.1",
69
- "metro-memory-fs": "0.81.0-alpha.1",
68
+ "metro-babel-register": "0.81.0",
69
+ "metro-memory-fs": "0.81.0",
70
70
  "mock-req": "^0.2.0",
71
71
  "mock-res": "^0.6.0",
72
72
  "stack-trace": "^0.0.10"
package/src/Bundler.js CHANGED
@@ -5,7 +5,7 @@ const DependencyGraph = require("./node-haste/DependencyGraph");
5
5
  class Bundler {
6
6
  constructor(config, options) {
7
7
  this._depGraph = new DependencyGraph(config, options);
8
- this._readyPromise = this._depGraph
8
+ this._initializedPromise = this._depGraph
9
9
  .ready()
10
10
  .then(() => {
11
11
  config.reporter.update({
@@ -30,16 +30,16 @@ class Bundler {
30
30
  return this._depGraph.getWatcher();
31
31
  }
32
32
  async end() {
33
- await this._depGraph.ready();
34
- this._transformer.end();
35
- this._depGraph.end();
33
+ await this.ready();
34
+ await this._transformer.end();
35
+ await this._depGraph.end();
36
36
  }
37
37
  async getDependencyGraph() {
38
- await this._depGraph.ready();
38
+ await this.ready();
39
39
  return this._depGraph;
40
40
  }
41
41
  async transformFile(filePath, transformOptions, fileBuffer) {
42
- await this._depGraph.ready();
42
+ await this.ready();
43
43
  return this._transformer.transformFile(
44
44
  filePath,
45
45
  transformOptions,
@@ -47,7 +47,7 @@ class Bundler {
47
47
  );
48
48
  }
49
49
  async ready() {
50
- await this._readyPromise;
50
+ await this._initializedPromise;
51
51
  }
52
52
  }
53
53
  module.exports = Bundler;
@@ -26,13 +26,13 @@ export type BundlerOptions = $ReadOnly<{
26
26
 
27
27
  class Bundler {
28
28
  _depGraph: DependencyGraph;
29
- _readyPromise: Promise<void>;
29
+ _initializedPromise: Promise<void>;
30
30
  _transformer: Transformer;
31
31
 
32
32
  constructor(config: ConfigT, options?: BundlerOptions) {
33
33
  this._depGraph = new DependencyGraph(config, options);
34
34
 
35
- this._readyPromise = this._depGraph
35
+ this._initializedPromise = this._depGraph
36
36
  .ready()
37
37
  .then(() => {
38
38
  config.reporter.update({type: 'transformer_load_started'});
@@ -55,14 +55,15 @@ class Bundler {
55
55
  }
56
56
 
57
57
  async end(): Promise<void> {
58
- await this._depGraph.ready();
58
+ await this.ready();
59
59
 
60
- this._transformer.end();
61
- this._depGraph.end();
60
+ await this._transformer.end();
61
+ await this._depGraph.end();
62
62
  }
63
63
 
64
64
  async getDependencyGraph(): Promise<DependencyGraph> {
65
- await this._depGraph.ready();
65
+ await this.ready();
66
+
66
67
  return this._depGraph;
67
68
  }
68
69
 
@@ -74,7 +75,7 @@ class Bundler {
74
75
  ): Promise<TransformResultWithSource<>> {
75
76
  // We need to be sure that the DependencyGraph has been initialized.
76
77
  // TODO: Remove this ugly hack!
77
- await this._depGraph.ready();
78
+ await this.ready();
78
79
 
79
80
  return this._transformer.transformFile(
80
81
  filePath,
@@ -85,7 +86,7 @@ class Bundler {
85
86
 
86
87
  // Waits for the bundler to become ready.
87
88
  async ready(): Promise<void> {
88
- await this._readyPromise;
89
+ await this._initializedPromise;
89
90
  }
90
91
  }
91
92
 
@@ -132,8 +132,8 @@ class Transformer {
132
132
  },
133
133
  };
134
134
  }
135
- end() {
136
- this._workerFarm.kill();
135
+ async end() {
136
+ await this._workerFarm.kill();
137
137
  }
138
138
  }
139
139
  function verifyRootExists(root) {
@@ -188,9 +188,8 @@ class Transformer {
188
188
  };
189
189
  }
190
190
 
191
- end(): void {
192
- // $FlowFixMe[unused-promise]
193
- this._workerFarm.kill();
191
+ async end(): Promise<void> {
192
+ await this._workerFarm.kill();
194
193
  }
195
194
  }
196
195
 
@@ -24,9 +24,9 @@ class IncrementalBundler {
24
24
  this._bundler = new Bundler(config, options);
25
25
  this._deltaBundler = new DeltaBundler(this._bundler.getWatcher());
26
26
  }
27
- end() {
27
+ async end() {
28
28
  this._deltaBundler.end();
29
- this._bundler.end();
29
+ await this._bundler.end();
30
30
  }
31
31
  getBundler() {
32
32
  return this._bundler;
@@ -79,10 +79,9 @@ class IncrementalBundler {
79
79
  this._deltaBundler = new DeltaBundler(this._bundler.getWatcher());
80
80
  }
81
81
 
82
- end(): void {
82
+ async end(): Promise<void> {
83
83
  this._deltaBundler.end();
84
- // $FlowFixMe[unused-promise]
85
- this._bundler.end();
84
+ await this._bundler.end();
86
85
  }
87
86
 
88
87
  getBundler(): Bundler {
package/src/Server.js CHANGED
@@ -87,9 +87,9 @@ class Server {
87
87
  });
88
88
  this._nextBundleBuildNumber = 1;
89
89
  }
90
- end() {
90
+ async end() {
91
91
  if (!this._isEnded) {
92
- this._bundler.end();
92
+ await this._bundler.end();
93
93
  this._isEnded = true;
94
94
  }
95
95
  }
@@ -196,9 +196,9 @@ class Server {
196
196
  this._nextBundleBuildNumber = 1;
197
197
  }
198
198
 
199
- end() {
199
+ async end() {
200
200
  if (!this._isEnded) {
201
- this._bundler.end();
201
+ await this._bundler.end();
202
202
  this._isEnded = true;
203
203
  }
204
204
  }
@@ -37,7 +37,7 @@ async function dependencies(args, config) {
37
37
  outStream.write(modulePath + "\n");
38
38
  }
39
39
  });
40
- server.end();
40
+ await server.end();
41
41
  return args.output != null
42
42
  ? promisify(outStream.end).bind(outStream)()
43
43
  : Promise.resolve();
@@ -74,7 +74,7 @@ async function dependencies(args: Args, config: ConfigT) {
74
74
  }
75
75
  });
76
76
 
77
- server.end();
77
+ await server.end();
78
78
  return args.output != null
79
79
  ? // $FlowFixMe[method-unbinding]
80
80
  promisify(outStream.end).bind(outStream)()
package/src/index.flow.js CHANGED
@@ -98,8 +98,8 @@ const createConnectMiddleware = async function (config, options) {
98
98
  },
99
99
  metroServer,
100
100
  middleware: enhancedMiddleware,
101
- end() {
102
- metroServer.end();
101
+ async end() {
102
+ await metroServer.end();
103
103
  },
104
104
  };
105
105
  };
@@ -111,6 +111,7 @@ exports.runServer = async (
111
111
  host,
112
112
  onError,
113
113
  onReady,
114
+ onClose,
114
115
  secureServerOptions,
115
116
  secure,
116
117
  secureCert,
@@ -132,14 +133,15 @@ exports.runServer = async (
132
133
  }
133
134
  const connect = require("connect");
134
135
  const serverApp = connect();
135
- const { middleware, end, metroServer } = await createConnectMiddleware(
136
- config,
137
- {
138
- hasReducedPerformance,
139
- waitForBundler,
140
- watch,
141
- }
142
- );
136
+ const {
137
+ middleware,
138
+ end: endMiddleware,
139
+ metroServer,
140
+ } = await createConnectMiddleware(config, {
141
+ hasReducedPerformance,
142
+ waitForBundler,
143
+ watch,
144
+ });
143
145
  for (const handler of unstable_extraMiddleware ?? []) {
144
146
  serverApp.use(handler);
145
147
  }
@@ -160,11 +162,10 @@ exports.runServer = async (
160
162
  }
161
163
  return new Promise((resolve, reject) => {
162
164
  httpServer.on("error", (error) => {
163
- if (onError) {
164
- onError(error);
165
- }
166
- reject(error);
167
- end();
165
+ endMiddleware().finally(() => {
166
+ onError?.(error);
167
+ reject(error);
168
+ });
168
169
  });
169
170
  httpServer.listen(config.server.port, host, () => {
170
171
  const { address, port, family } = httpServer.address();
@@ -174,9 +175,6 @@ exports.runServer = async (
174
175
  port,
175
176
  family,
176
177
  });
177
- if (onReady) {
178
- onReady(httpServer);
179
- }
180
178
  websocketEndpoints = {
181
179
  ...websocketEndpoints,
182
180
  "/hot": createWebsocketServer({
@@ -202,11 +200,16 @@ exports.runServer = async (
202
200
  socket.destroy();
203
201
  }
204
202
  });
203
+ if (onReady) {
204
+ onReady(httpServer);
205
+ }
205
206
  resolve(httpServer);
206
207
  });
207
208
  httpServer.timeout = 0;
208
209
  httpServer.on("close", () => {
209
- end();
210
+ endMiddleware()?.finally(() => {
211
+ onClose?.();
212
+ });
210
213
  });
211
214
  });
212
215
  };
@@ -301,7 +304,7 @@ exports.buildGraph = async function (
301
304
  }
302
305
  );
303
306
  } finally {
304
- bundler.end();
307
+ await bundler.end();
305
308
  }
306
309
  };
307
310
  exports.attachMetroCli = function (yargs, options = {}) {
@@ -52,7 +52,7 @@ const {parse} = require('url');
52
52
 
53
53
  type MetroMiddleWare = {
54
54
  attachHmrServer: (httpServer: HttpServer | HttpsServer) => void,
55
- end: () => void,
55
+ end: () => Promise<void>,
56
56
  metroServer: MetroServer,
57
57
  middleware: Middleware,
58
58
  };
@@ -67,6 +67,7 @@ export type RunServerOptions = $ReadOnly<{
67
67
  host?: string,
68
68
  onError?: (Error & {code?: string}) => void,
69
69
  onReady?: (server: HttpServer | HttpsServer) => void,
70
+ onClose?: () => void,
70
71
  secureServerOptions?: Object,
71
72
  secure?: boolean, // deprecated
72
73
  secureCert?: string, // deprecated
@@ -223,8 +224,8 @@ const createConnectMiddleware = async function (
223
224
  },
224
225
  metroServer,
225
226
  middleware: enhancedMiddleware,
226
- end(): void {
227
- metroServer.end();
227
+ async end(): Promise<void> {
228
+ await metroServer.end();
228
229
  },
229
230
  };
230
231
  };
@@ -237,6 +238,7 @@ exports.runServer = async (
237
238
  host,
238
239
  onError,
239
240
  onReady,
241
+ onClose,
240
242
  secureServerOptions,
241
243
  secure, //deprecated
242
244
  secureCert, // deprecated
@@ -263,7 +265,11 @@ exports.runServer = async (
263
265
 
264
266
  const serverApp = connect();
265
267
 
266
- const {middleware, end, metroServer} = await createConnectMiddleware(config, {
268
+ const {
269
+ middleware,
270
+ end: endMiddleware,
271
+ metroServer,
272
+ } = await createConnectMiddleware(config, {
267
273
  hasReducedPerformance,
268
274
  waitForBundler,
269
275
  watch,
@@ -297,11 +303,10 @@ exports.runServer = async (
297
303
  reject: mixed => mixed,
298
304
  ) => {
299
305
  httpServer.on('error', error => {
300
- if (onError) {
301
- onError(error);
302
- }
303
- reject(error);
304
- end();
306
+ endMiddleware().finally(() => {
307
+ onError?.(error);
308
+ reject(error);
309
+ });
305
310
  });
306
311
 
307
312
  httpServer.listen(config.server.port, host, () => {
@@ -313,10 +318,6 @@ exports.runServer = async (
313
318
  family,
314
319
  });
315
320
 
316
- if (onReady) {
317
- onReady(httpServer);
318
- }
319
-
320
321
  websocketEndpoints = {
321
322
  ...websocketEndpoints,
322
323
  '/hot': createWebsocketServer({
@@ -344,6 +345,10 @@ exports.runServer = async (
344
345
  }
345
346
  });
346
347
 
348
+ if (onReady) {
349
+ onReady(httpServer);
350
+ }
351
+
347
352
  resolve(httpServer);
348
353
  });
349
354
 
@@ -353,7 +358,9 @@ exports.runServer = async (
353
358
  httpServer.timeout = 0;
354
359
 
355
360
  httpServer.on('close', () => {
356
- end();
361
+ endMiddleware()?.finally(() => {
362
+ onClose?.();
363
+ });
357
364
  });
358
365
  },
359
366
  );
@@ -463,7 +470,7 @@ exports.buildGraph = async function (
463
470
  {customResolverOptions, dev},
464
471
  );
465
472
  } finally {
466
- bundler.end();
473
+ await bundler.end();
467
474
  }
468
475
  };
469
476
 
@@ -8,7 +8,6 @@ class BatchProcessor {
8
8
  this._queue = [];
9
9
  this._timeoutHandle = null;
10
10
  this._currentProcessCount = 0;
11
- this._processQueue = this._processQueue.bind(this);
12
11
  }
13
12
  _onBatchFinished() {
14
13
  this._currentProcessCount--;
@@ -34,20 +33,20 @@ class BatchProcessor {
34
33
  this._currentProcessCount++;
35
34
  const jobs = this._queue.splice(0, this._options.maximumItems);
36
35
  this._processBatch(jobs.map((job) => job.item)).then(
37
- this._onBatchResults.bind(this, jobs),
38
- this._onBatchError.bind(this, jobs)
36
+ (results) => this._onBatchResults(jobs, results),
37
+ (error) => this._onBatchError(jobs, error)
39
38
  );
40
39
  }
41
40
  }
42
41
  _processQueueOnceReady() {
43
42
  if (this._queue.length >= this._options.maximumItems) {
44
43
  clearTimeout(this._timeoutHandle);
45
- process.nextTick(this._processQueue);
44
+ process.nextTick(() => this._processQueue());
46
45
  return;
47
46
  }
48
47
  if (this._timeoutHandle == null) {
49
48
  this._timeoutHandle = setTimeout(
50
- this._processQueue,
49
+ () => this._processQueue(),
51
50
  this._options.maximumDelayMs
52
51
  );
53
52
  }
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @flow
7
+ * @flow strict
8
8
  * @format
9
9
  * @oncall react_native
10
10
  */
@@ -54,8 +54,6 @@ class BatchProcessor<TItem, TResult> {
54
54
  this._queue = [];
55
55
  this._timeoutHandle = null;
56
56
  this._currentProcessCount = 0;
57
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
58
- (this: any)._processQueue = this._processQueue.bind(this);
59
57
  }
60
58
 
61
59
  _onBatchFinished(): void {
@@ -90,10 +88,8 @@ class BatchProcessor<TItem, TResult> {
90
88
  this._processBatch(
91
89
  jobs.map((job: QueueItem<TItem, TResult>) => job.item),
92
90
  ).then(
93
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
94
- this._onBatchResults.bind(this, jobs),
95
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
96
- this._onBatchError.bind(this, jobs),
91
+ results => this._onBatchResults(jobs, results),
92
+ error => this._onBatchError(jobs, error),
97
93
  );
98
94
  }
99
95
  }
@@ -101,14 +97,12 @@ class BatchProcessor<TItem, TResult> {
101
97
  _processQueueOnceReady(): void {
102
98
  if (this._queue.length >= this._options.maximumItems) {
103
99
  clearTimeout(this._timeoutHandle);
104
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
105
- process.nextTick(this._processQueue);
100
+ process.nextTick(() => this._processQueue());
106
101
  return;
107
102
  }
108
103
  if (this._timeoutHandle == null) {
109
104
  this._timeoutHandle = setTimeout(
110
- // $FlowFixMe[method-unbinding] added when improving typing for this parameters
111
- this._processQueue,
105
+ () => this._processQueue(),
112
106
  this._options.maximumDelayMs,
113
107
  );
114
108
  }
@@ -160,6 +160,15 @@ class TerminalReporter {
160
160
  case "client_log":
161
161
  logToConsole(this.terminal, event.level, event.mode, ...event.data);
162
162
  break;
163
+ case "unstable_server_log":
164
+ const logFn = {
165
+ info: reporting.logInfo,
166
+ warn: reporting.logWarning,
167
+ error: reporting.logError,
168
+ }[event.level];
169
+ const [format, ...args] = [].concat(event.data);
170
+ logFn(this.terminal, String(format), ...args);
171
+ break;
163
172
  case "dep_graph_loading":
164
173
  const color = event.hasReducedPerformance ? chalk.red : chalk.blue;
165
174
  const version = "v" + require("../../package.json").version;
@@ -257,8 +266,11 @@ class TerminalReporter {
257
266
  case "bundle_transform_progressed_throttled":
258
267
  this._updateBundleProgress(event);
259
268
  break;
260
- case "unstable_set_interaction_status":
261
- this._interactionStatus = event.status;
269
+ case "unstable_server_menu_updated":
270
+ this._interactionStatus = event.message;
271
+ break;
272
+ case "unstable_server_menu_cleared":
273
+ this._interactionStatus = null;
262
274
  break;
263
275
  }
264
276
  }
@@ -41,8 +41,18 @@ export type TerminalReportableEvent =
41
41
  ...
42
42
  }
43
43
  | {
44
- type: 'unstable_set_interaction_status',
45
- status: ?string,
44
+ type: 'unstable_server_log',
45
+ level: 'info' | 'warn' | 'error',
46
+ data: string | Array<mixed>,
47
+ ...
48
+ }
49
+ | {
50
+ type: 'unstable_server_menu_updated',
51
+ message: string,
52
+ ...
53
+ }
54
+ | {
55
+ type: 'unstable_server_menu_cleared',
46
56
  ...
47
57
  };
48
58
 
@@ -251,6 +261,15 @@ class TerminalReporter {
251
261
  case 'client_log':
252
262
  logToConsole(this.terminal, event.level, event.mode, ...event.data);
253
263
  break;
264
+ case 'unstable_server_log':
265
+ const logFn = {
266
+ info: reporting.logInfo,
267
+ warn: reporting.logWarning,
268
+ error: reporting.logError,
269
+ }[event.level];
270
+ const [format, ...args] = [].concat(event.data);
271
+ logFn(this.terminal, String(format), ...args);
272
+ break;
254
273
  case 'dep_graph_loading':
255
274
  const color = event.hasReducedPerformance ? chalk.red : chalk.blue;
256
275
  const version = 'v' + require('../../package.json').version;
@@ -385,8 +404,11 @@ class TerminalReporter {
385
404
  case 'bundle_transform_progressed_throttled':
386
405
  this._updateBundleProgress(event);
387
406
  break;
388
- case 'unstable_set_interaction_status':
389
- this._interactionStatus = event.status;
407
+ case 'unstable_server_menu_updated':
408
+ this._interactionStatus = event.message;
409
+ break;
410
+ case 'unstable_server_menu_cleared':
411
+ this._interactionStatus = null;
390
412
  break;
391
413
  }
392
414
  }
@@ -5,20 +5,25 @@ const stripAnsi = require("strip-ansi");
5
5
  const util = require("util");
6
6
  function logWarning(terminal, format, ...args) {
7
7
  const str = util.format(format, ...args);
8
- terminal.log("%s: %s", chalk.yellow("warning"), str);
8
+ terminal.log("%s %s", chalk.yellow.inverse.bold(" WARN "), str);
9
9
  }
10
10
  function logError(terminal, format, ...args) {
11
11
  terminal.log(
12
- "%s: %s",
13
- chalk.red("error"),
12
+ "%s %s",
13
+ chalk.red.inverse.bold(" ERROR "),
14
14
  util.format(chalk.supportsColor ? format : stripAnsi(format), ...args)
15
15
  );
16
16
  }
17
+ function logInfo(terminal, format, ...args) {
18
+ const str = util.format(format, ...args);
19
+ terminal.log("%s %s", chalk.cyan.inverse.bold(" INFO "), str);
20
+ }
17
21
  const nullReporter = {
18
22
  update() {},
19
23
  };
20
24
  module.exports = {
21
25
  logWarning,
22
26
  logError,
27
+ logInfo,
23
28
  nullReporter,
24
29
  };
@@ -189,7 +189,7 @@ function logWarning(
189
189
  ...args: Array<mixed>
190
190
  ): void {
191
191
  const str = util.format(format, ...args);
192
- terminal.log('%s: %s', chalk.yellow('warning'), str);
192
+ terminal.log('%s %s', chalk.yellow.inverse.bold(' WARN '), str);
193
193
  }
194
194
 
195
195
  /**
@@ -201,8 +201,8 @@ function logError(
201
201
  ...args: Array<mixed>
202
202
  ): void {
203
203
  terminal.log(
204
- '%s: %s',
205
- chalk.red('error'),
204
+ '%s %s',
205
+ chalk.red.inverse.bold(' ERROR '),
206
206
  // Syntax errors may have colors applied for displaying code frames
207
207
  // in various places outside of where Metro is currently running.
208
208
  // If the current terminal does not support color, we'll strip the colors
@@ -211,6 +211,18 @@ function logError(
211
211
  );
212
212
  }
213
213
 
214
+ /**
215
+ * Similar to `logWarning`, but for informational messages.
216
+ */
217
+ function logInfo(
218
+ terminal: Terminal,
219
+ format: string,
220
+ ...args: Array<mixed>
221
+ ): void {
222
+ const str = util.format(format, ...args);
223
+ terminal.log('%s %s', chalk.cyan.inverse.bold(' INFO '), str);
224
+ }
225
+
214
226
  /**
215
227
  * A reporter that does nothing. Errors and warnings will be swallowed, that
216
228
  * is generally not what you want.
@@ -220,5 +232,6 @@ const nullReporter = {update(): void {}};
220
232
  module.exports = {
221
233
  logWarning,
222
234
  logError,
235
+ logInfo,
223
236
  nullReporter,
224
237
  };
@@ -58,6 +58,7 @@ class ModuleResolver {
58
58
  disableHierarchicalLookup,
59
59
  doesFileExist,
60
60
  extraNodeModules,
61
+ fileSystemLookup,
61
62
  mainFields,
62
63
  nodeModulesPaths,
63
64
  preferNativePlatform,
@@ -67,7 +68,6 @@ class ModuleResolver {
67
68
  unstable_conditionNames,
68
69
  unstable_conditionsByPlatform,
69
70
  unstable_enablePackageExports,
70
- unstable_fileSystemLookup,
71
71
  } = this._options;
72
72
  try {
73
73
  const result = Resolver.resolve(
@@ -79,6 +79,7 @@ class ModuleResolver {
79
79
  disableHierarchicalLookup,
80
80
  doesFileExist,
81
81
  extraNodeModules,
82
+ fileSystemLookup,
82
83
  mainFields,
83
84
  nodeModulesPaths,
84
85
  preferNativePlatform,
@@ -88,7 +89,6 @@ class ModuleResolver {
88
89
  unstable_conditionNames,
89
90
  unstable_conditionsByPlatform,
90
91
  unstable_enablePackageExports,
91
- unstable_fileSystemLookup,
92
92
  unstable_logWarning: this._logWarning,
93
93
  customResolverOptions: resolverOptions.customResolverOptions ?? {},
94
94
  originModulePath: fromModule.path,
@@ -127,8 +127,17 @@ class ModuleResolver {
127
127
  dependency,
128
128
  }
129
129
  );
130
- }
131
- if (error instanceof Resolver.FailedToResolveNameError) {
130
+ } else if (error instanceof Resolver.FailedToResolveUnsupportedError) {
131
+ throw new UnableToResolveError(
132
+ fromModule.path,
133
+ dependency.name,
134
+ error.message,
135
+ {
136
+ cause: error,
137
+ dependency,
138
+ }
139
+ );
140
+ } else if (error instanceof Resolver.FailedToResolveNameError) {
132
141
  const dirPaths = error.dirPaths;
133
142
  const extraPaths = error.extraPaths;
134
143
  const displayDirPaths = dirPaths
@@ -66,6 +66,7 @@ type Options<TPackage> = $ReadOnly<{
66
66
  doesFileExist: DoesFileExist,
67
67
  emptyModulePath: string,
68
68
  extraNodeModules: ?Object,
69
+ fileSystemLookup: FileSystemLookup,
69
70
  getHasteModulePath: (name: string, platform: ?string) => ?string,
70
71
  getHastePackagePath: (name: string, platform: ?string) => ?string,
71
72
  mainFields: $ReadOnlyArray<string>,
@@ -82,7 +83,6 @@ type Options<TPackage> = $ReadOnly<{
82
83
  [platform: string]: $ReadOnlyArray<string>,
83
84
  }>,
84
85
  unstable_enablePackageExports: boolean,
85
- unstable_fileSystemLookup: ?FileSystemLookup,
86
86
  }>;
87
87
 
88
88
  class ModuleResolver<TPackage: Packageish> {
@@ -142,6 +142,7 @@ class ModuleResolver<TPackage: Packageish> {
142
142
  disableHierarchicalLookup,
143
143
  doesFileExist,
144
144
  extraNodeModules,
145
+ fileSystemLookup,
145
146
  mainFields,
146
147
  nodeModulesPaths,
147
148
  preferNativePlatform,
@@ -151,7 +152,6 @@ class ModuleResolver<TPackage: Packageish> {
151
152
  unstable_conditionNames,
152
153
  unstable_conditionsByPlatform,
153
154
  unstable_enablePackageExports,
154
- unstable_fileSystemLookup,
155
155
  } = this._options;
156
156
 
157
157
  try {
@@ -164,6 +164,7 @@ class ModuleResolver<TPackage: Packageish> {
164
164
  disableHierarchicalLookup,
165
165
  doesFileExist,
166
166
  extraNodeModules,
167
+ fileSystemLookup,
167
168
  mainFields,
168
169
  nodeModulesPaths,
169
170
  preferNativePlatform,
@@ -173,7 +174,6 @@ class ModuleResolver<TPackage: Packageish> {
173
174
  unstable_conditionNames,
174
175
  unstable_conditionsByPlatform,
175
176
  unstable_enablePackageExports,
176
- unstable_fileSystemLookup,
177
177
  unstable_logWarning: this._logWarning,
178
178
  customResolverOptions: resolverOptions.customResolverOptions ?? {},
179
179
  originModulePath: fromModule.path,
@@ -210,8 +210,14 @@ class ModuleResolver<TPackage: Packageish> {
210
210
  dependency,
211
211
  },
212
212
  );
213
- }
214
- if (error instanceof Resolver.FailedToResolveNameError) {
213
+ } else if (error instanceof Resolver.FailedToResolveUnsupportedError) {
214
+ throw new UnableToResolveError(
215
+ fromModule.path,
216
+ dependency.name,
217
+ error.message,
218
+ {cause: error, dependency},
219
+ );
220
+ } else if (error instanceof Resolver.FailedToResolveNameError) {
215
221
  const dirPaths = error.dirPaths;
216
222
  const extraPaths = error.extraPaths;
217
223
  const displayDirPaths = dirPaths
@@ -42,23 +42,25 @@ class DependencyGraph extends EventEmitter {
42
42
  fileMap.setMaxListeners(1000);
43
43
  this._haste = fileMap;
44
44
  this._haste.on("status", (status) => this._onWatcherStatus(status));
45
- this._readyPromise = fileMap.build().then(({ fileSystem, hasteMap }) => {
46
- log(createActionEndEntry(initializingMetroLogEntry));
47
- config.reporter.update({
48
- type: "dep_graph_loaded",
45
+ this._initializedPromise = fileMap
46
+ .build()
47
+ .then(({ fileSystem, hasteMap }) => {
48
+ log(createActionEndEntry(initializingMetroLogEntry));
49
+ config.reporter.update({
50
+ type: "dep_graph_loaded",
51
+ });
52
+ this._fileSystem = fileSystem;
53
+ this._hasteMap = hasteMap;
54
+ this._haste.on("change", (changeEvent) =>
55
+ this._onHasteChange(changeEvent)
56
+ );
57
+ this._haste.on("healthCheck", (result) =>
58
+ this._onWatcherHealthCheck(result)
59
+ );
60
+ this._resolutionCache = new Map();
61
+ this._moduleCache = this._createModuleCache();
62
+ this._createModuleResolver();
49
63
  });
50
- this._fileSystem = fileSystem;
51
- this._hasteMap = hasteMap;
52
- this._haste.on("change", (changeEvent) =>
53
- this._onHasteChange(changeEvent)
54
- );
55
- this._haste.on("healthCheck", (result) =>
56
- this._onWatcherHealthCheck(result)
57
- );
58
- this._resolutionCache = new Map();
59
- this._moduleCache = this._createModuleCache();
60
- this._createModuleResolver();
61
- });
62
64
  }
63
65
  _onWatcherHealthCheck(result) {
64
66
  this._config.reporter.update({
@@ -73,7 +75,7 @@ class DependencyGraph extends EventEmitter {
73
75
  });
74
76
  }
75
77
  async ready() {
76
- await this._readyPromise;
78
+ await this._initializedPromise;
77
79
  }
78
80
  static async load(config, options) {
79
81
  const self = new DependencyGraph(config, options);
@@ -115,6 +117,7 @@ class DependencyGraph extends EventEmitter {
115
117
  doesFileExist: this._doesFileExist,
116
118
  emptyModulePath: this._config.resolver.emptyModulePath,
117
119
  extraNodeModules: this._config.resolver.extraNodeModules,
120
+ fileSystemLookup,
118
121
  getHasteModulePath: (name, platform) =>
119
122
  this._hasteMap.getModule(name, platform, true),
120
123
  getHastePackagePath: (name, platform) =>
@@ -144,7 +147,6 @@ class DependencyGraph extends EventEmitter {
144
147
  this._config.resolver.unstable_conditionsByPlatform,
145
148
  unstable_enablePackageExports:
146
149
  this._config.resolver.unstable_enablePackageExports,
147
- unstable_fileSystemLookup: fileSystemLookup,
148
150
  });
149
151
  }
150
152
  _getClosestPackage(absoluteModulePath) {
@@ -186,8 +188,9 @@ class DependencyGraph extends EventEmitter {
186
188
  getWatcher() {
187
189
  return this._haste;
188
190
  }
189
- end() {
190
- this._haste.end();
191
+ async end() {
192
+ await this.ready();
193
+ await this._haste.end();
191
194
  }
192
195
  matchFilesWithContext(from, context) {
193
196
  return this._fileSystem.matchFiles({
@@ -79,7 +79,7 @@ class DependencyGraph extends EventEmitter {
79
79
  >,
80
80
  >,
81
81
  >;
82
- _readyPromise: Promise<void>;
82
+ _initializedPromise: Promise<void>;
83
83
 
84
84
  constructor(
85
85
  config: ConfigT,
@@ -110,21 +110,25 @@ class DependencyGraph extends EventEmitter {
110
110
  this._haste = fileMap;
111
111
  this._haste.on('status', status => this._onWatcherStatus(status));
112
112
 
113
- this._readyPromise = fileMap.build().then(({fileSystem, hasteMap}) => {
114
- log(createActionEndEntry(initializingMetroLogEntry));
115
- config.reporter.update({type: 'dep_graph_loaded'});
113
+ this._initializedPromise = fileMap
114
+ .build()
115
+ .then(({fileSystem, hasteMap}) => {
116
+ log(createActionEndEntry(initializingMetroLogEntry));
117
+ config.reporter.update({type: 'dep_graph_loaded'});
116
118
 
117
- this._fileSystem = fileSystem;
118
- this._hasteMap = hasteMap;
119
+ this._fileSystem = fileSystem;
120
+ this._hasteMap = hasteMap;
119
121
 
120
- this._haste.on('change', changeEvent => this._onHasteChange(changeEvent));
121
- this._haste.on('healthCheck', result =>
122
- this._onWatcherHealthCheck(result),
123
- );
124
- this._resolutionCache = new Map();
125
- this._moduleCache = this._createModuleCache();
126
- this._createModuleResolver();
127
- });
122
+ this._haste.on('change', changeEvent =>
123
+ this._onHasteChange(changeEvent),
124
+ );
125
+ this._haste.on('healthCheck', result =>
126
+ this._onWatcherHealthCheck(result),
127
+ );
128
+ this._resolutionCache = new Map();
129
+ this._moduleCache = this._createModuleCache();
130
+ this._createModuleResolver();
131
+ });
128
132
  }
129
133
 
130
134
  _onWatcherHealthCheck(result: HealthCheckResult) {
@@ -138,7 +142,7 @@ class DependencyGraph extends EventEmitter {
138
142
  // Waits for the dependency graph to become ready after initialisation.
139
143
  // Don't read anything from the graph until this resolves.
140
144
  async ready(): Promise<void> {
141
- await this._readyPromise;
145
+ await this._initializedPromise;
142
146
  }
143
147
 
144
148
  // Creates the dependency graph and waits for it to become ready.
@@ -185,6 +189,7 @@ class DependencyGraph extends EventEmitter {
185
189
  doesFileExist: this._doesFileExist,
186
190
  emptyModulePath: this._config.resolver.emptyModulePath,
187
191
  extraNodeModules: this._config.resolver.extraNodeModules,
192
+ fileSystemLookup,
188
193
  getHasteModulePath: (name, platform) =>
189
194
  this._hasteMap.getModule(name, platform, true),
190
195
  getHastePackagePath: (name, platform) =>
@@ -215,7 +220,6 @@ class DependencyGraph extends EventEmitter {
215
220
  this._config.resolver.unstable_conditionsByPlatform,
216
221
  unstable_enablePackageExports:
217
222
  this._config.resolver.unstable_enablePackageExports,
218
- unstable_fileSystemLookup: fileSystemLookup,
219
223
  });
220
224
  }
221
225
 
@@ -268,9 +272,9 @@ class DependencyGraph extends EventEmitter {
268
272
  return this._haste;
269
273
  }
270
274
 
271
- end() {
272
- // $FlowFixMe[unused-promise]
273
- this._haste.end();
275
+ async end() {
276
+ await this.ready();
277
+ await this._haste.end();
274
278
  }
275
279
 
276
280
  /** Given a search context, return a list of file paths matching the query. */