metro 0.82.4 → 0.83.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 (76) hide show
  1. package/package.json +18 -21
  2. package/src/DeltaBundler/DeltaCalculator.js +5 -1
  3. package/src/DeltaBundler/Graph.js +37 -10
  4. package/src/DeltaBundler/Graph.js.flow +49 -22
  5. package/src/DeltaBundler/Serializers/getRamBundleInfo.js.flow +1 -0
  6. package/src/DeltaBundler/Serializers/helpers/getTransitiveDependencies.js +4 -1
  7. package/src/DeltaBundler/Serializers/helpers/getTransitiveDependencies.js.flow +5 -1
  8. package/src/DeltaBundler/Serializers/helpers/js.js +4 -0
  9. package/src/DeltaBundler/Serializers/helpers/js.js.flow +6 -0
  10. package/src/DeltaBundler/Transformer.js +5 -2
  11. package/src/DeltaBundler/Transformer.js.flow +3 -2
  12. package/src/DeltaBundler/Worker.d.ts +7 -9
  13. package/src/DeltaBundler/Worker.flow.js.flow +2 -2
  14. package/src/DeltaBundler/WorkerFarm.js +2 -2
  15. package/src/DeltaBundler/WorkerFarm.js.flow +2 -6
  16. package/src/DeltaBundler/buildSubgraph.js +21 -15
  17. package/src/DeltaBundler/buildSubgraph.js.flow +21 -21
  18. package/src/DeltaBundler/getTransformCacheKey.js +1 -1
  19. package/src/DeltaBundler/getTransformCacheKey.js.flow +1 -1
  20. package/src/DeltaBundler/types.flow.js +5 -1
  21. package/src/DeltaBundler/types.flow.js.flow +7 -1
  22. package/src/ModuleGraph/worker/JsFileWrapping.js +39 -9
  23. package/src/ModuleGraph/worker/JsFileWrapping.js.flow +32 -5
  24. package/src/ModuleGraph/worker/collectDependencies.js.flow +7 -1
  25. package/src/Server/symbolicate.js +4 -2
  26. package/src/Server/symbolicate.js.flow +4 -2
  27. package/src/Server.d.ts +6 -1
  28. package/src/Server.js +51 -14
  29. package/src/Server.js.flow +75 -21
  30. package/src/commands/build.js +5 -1
  31. package/src/commands/serve.js +4 -1
  32. package/src/commands/serve.js.flow +4 -1
  33. package/src/index.d.ts +13 -7
  34. package/src/index.flow.js +9 -3
  35. package/src/index.flow.js.flow +69 -63
  36. package/src/integration_tests/basic_bundle/build-errors/cannot-resolve-import.js +5 -1
  37. package/src/integration_tests/basic_bundle/build-errors/inline-requires-cannot-resolve-import.js +5 -1
  38. package/src/integration_tests/basic_bundle/import-export/index.js +11 -3
  39. package/src/integration_tests/basic_bundle/optional-dependencies/index.js +20 -0
  40. package/src/integration_tests/basic_bundle/optional-dependencies/index.js.flow +34 -0
  41. package/src/integration_tests/basic_bundle/optional-dependencies/optional-b.js +3 -0
  42. package/src/integration_tests/basic_bundle/optional-dependencies/optional-b.js.flow +11 -0
  43. package/src/integration_tests/basic_bundle/optional-dependencies/optional-c.js +3 -0
  44. package/src/integration_tests/basic_bundle/optional-dependencies/optional-c.js.flow +11 -0
  45. package/src/integration_tests/basic_bundle/optional-dependencies/required-a.js +3 -0
  46. package/src/integration_tests/basic_bundle/optional-dependencies/required-a.js.flow +11 -0
  47. package/src/lib/RamBundleParser.js.flow +1 -0
  48. package/src/lib/contextModule.js +5 -1
  49. package/src/lib/contextModuleTemplates.js +6 -2
  50. package/src/lib/createWebsocketServer.js +5 -1
  51. package/src/lib/createWebsocketServer.js.flow +1 -0
  52. package/src/lib/formatBundlingError.js.flow +1 -1
  53. package/src/lib/getAppendScripts.js +5 -1
  54. package/src/lib/getGraphId.js +1 -1
  55. package/src/lib/getGraphId.js.flow +1 -1
  56. package/src/lib/getPrependedScripts.js +6 -2
  57. package/src/lib/getPrependedScripts.js.flow +2 -2
  58. package/src/lib/isResolvedDependency.js +9 -0
  59. package/src/lib/isResolvedDependency.js.flow +18 -0
  60. package/src/lib/transformHelpers.js +6 -6
  61. package/src/lib/transformHelpers.js.flow +1 -5
  62. package/src/node-haste/DependencyGraph/ModuleResolution.js +2 -1
  63. package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +6 -2
  64. package/src/node-haste/DependencyGraph/createFileMap.js +6 -2
  65. package/src/node-haste/DependencyGraph.js +1 -1
  66. package/src/node-haste/DependencyGraph.js.flow +5 -4
  67. package/src/node-haste/Module.js +5 -1
  68. package/src/node-haste/Package.js.flow +1 -1
  69. package/src/shared/output/RamBundle/util.js +5 -1
  70. package/src/shared/output/RamBundle/util.js.flow +3 -1
  71. package/src/shared/output/RamBundle.js.flow +2 -0
  72. package/src/shared/output/bundle.d.ts +5 -1
  73. package/src/shared/output/bundle.flow.js +8 -5
  74. package/src/shared/output/bundle.flow.js.flow +11 -5
  75. package/src/shared/types.d.ts +4 -0
  76. package/src/shared/types.flow.js.flow +12 -8
@@ -12,18 +12,20 @@ import type {RequireContext} from '../lib/contextModule';
12
12
  import type {
13
13
  Dependency,
14
14
  ModuleData,
15
+ ResolvedDependency,
15
16
  ResolveFn,
16
17
  TransformFn,
17
18
  TransformResultDependency,
18
19
  } from './types.flow';
19
20
 
20
21
  import {deriveAbsolutePathFromContext} from '../lib/contextModule';
22
+ import {isResolvedDependency} from '../lib/isResolvedDependency';
21
23
  import path from 'path';
22
24
 
23
25
  type Parameters<T> = $ReadOnly<{
24
26
  resolve: ResolveFn,
25
27
  transform: TransformFn<T>,
26
- shouldTraverse: Dependency => boolean,
28
+ shouldTraverse: ResolvedDependency => boolean,
27
29
  }>;
28
30
 
29
31
  function resolveDependencies(
@@ -34,11 +36,11 @@ function resolveDependencies(
34
36
  dependencies: Map<string, Dependency>,
35
37
  resolvedContexts: Map<string, RequireContext>,
36
38
  } {
37
- const maybeResolvedDeps = new Map<string, void | Dependency>();
39
+ const maybeResolvedDeps = new Map<string, Dependency>();
38
40
  const resolvedContexts = new Map<string, RequireContext>();
39
41
 
40
42
  for (const dep of dependencies) {
41
- let resolvedDep;
43
+ let maybeResolvedDep: Dependency;
42
44
  const key = dep.data.key;
43
45
 
44
46
  // `require.context`
@@ -61,13 +63,13 @@ function resolveDependencies(
61
63
 
62
64
  resolvedContexts.set(key, resolvedContext);
63
65
 
64
- resolvedDep = {
66
+ maybeResolvedDep = {
65
67
  absolutePath,
66
68
  data: dep,
67
69
  };
68
70
  } else {
69
71
  try {
70
- resolvedDep = {
72
+ maybeResolvedDep = {
71
73
  absolutePath: resolve(parentPath, dep).filePath,
72
74
  data: dep,
73
75
  };
@@ -77,6 +79,9 @@ function resolveDependencies(
77
79
  if (dep.data.isOptional !== true) {
78
80
  throw error;
79
81
  }
82
+ maybeResolvedDep = {
83
+ data: dep,
84
+ };
80
85
  }
81
86
  }
82
87
 
@@ -85,21 +90,13 @@ function resolveDependencies(
85
90
  `resolveDependencies: Found duplicate dependency key '${key}' in ${parentPath}`,
86
91
  );
87
92
  }
88
- maybeResolvedDeps.set(key, resolvedDep);
93
+ maybeResolvedDeps.set(key, maybeResolvedDep);
89
94
  }
90
95
 
91
- const resolvedDeps = new Map<string, Dependency>();
92
- // Return just the dependencies we successfully resolved.
93
- // FIXME: This has a bad bug affecting all dependencies *after* an unresolved
94
- // optional dependency. We'll need to propagate the nulls all the way to the
95
- // serializer and the require() runtime to keep the dependency map from being
96
- // desynced from the contents of the module.
97
- for (const [key, resolvedDep] of maybeResolvedDeps) {
98
- if (resolvedDep) {
99
- resolvedDeps.set(key, resolvedDep);
100
- }
101
- }
102
- return {dependencies: resolvedDeps, resolvedContexts};
96
+ return {
97
+ dependencies: maybeResolvedDeps,
98
+ resolvedContexts,
99
+ };
103
100
  }
104
101
 
105
102
  export async function buildSubgraph<T>(
@@ -138,9 +135,12 @@ export async function buildSubgraph<T>(
138
135
  });
139
136
 
140
137
  await Promise.all(
141
- [...resolutionResult.dependencies]
142
- .filter(([key, dependency]) => shouldTraverse(dependency))
143
- .map(([key, dependency]) =>
138
+ [...resolutionResult.dependencies.values()]
139
+ .filter(
140
+ dependency =>
141
+ isResolvedDependency(dependency) && shouldTraverse(dependency),
142
+ )
143
+ .map(dependency =>
144
144
  visit(
145
145
  dependency.absolutePath,
146
146
  resolutionResult.resolvedContexts.get(dependency.data.data.key),
@@ -2,7 +2,7 @@
2
2
 
3
3
  const VERSION = require("../../package.json").version;
4
4
  const crypto = require("crypto");
5
- const getCacheKey = require("metro-cache-key");
5
+ const { getCacheKey } = require("metro-cache-key");
6
6
  function getTransformCacheKey(opts) {
7
7
  const { transformerPath, transformerConfig } = opts.transformerConfig;
8
8
  const Transformer = require.call(null, transformerPath);
@@ -16,7 +16,7 @@ import type {JsTransformerConfig} from 'metro-transform-worker';
16
16
 
17
17
  const VERSION = require('../../package.json').version;
18
18
  const crypto = require('crypto');
19
- const getCacheKey = require('metro-cache-key');
19
+ const {getCacheKey} = require('metro-cache-key');
20
20
 
21
21
  type CacheKeyProvider = {
22
22
  getCacheKey?: JsTransformerConfig => string,
@@ -2,5 +2,9 @@
2
2
 
3
3
  var _CountingSet = _interopRequireDefault(require("../lib/CountingSet"));
4
4
  function _interopRequireDefault(e) {
5
- return e && e.__esModule ? e : { default: e };
5
+ return e && e.__esModule
6
+ ? e
7
+ : {
8
+ default: e,
9
+ };
6
10
  }
@@ -61,11 +61,17 @@ export type TransformResultDependency = $ReadOnly<{
61
61
  }>,
62
62
  }>;
63
63
 
64
- export type Dependency = $ReadOnly<{
64
+ export type ResolvedDependency = $ReadOnly<{
65
65
  absolutePath: string,
66
66
  data: TransformResultDependency,
67
67
  }>;
68
68
 
69
+ export type Dependency =
70
+ | ResolvedDependency
71
+ | $ReadOnly<{
72
+ data: TransformResultDependency,
73
+ }>;
74
+
69
75
  export type Module<T = MixedOutput> = $ReadOnly<{
70
76
  dependencies: Map<string, Dependency>,
71
77
  inverseDependencies: CountingSet<string>,
@@ -15,10 +15,14 @@ function _getRequireWildcardCache(e) {
15
15
  function _interopRequireWildcard(e, r) {
16
16
  if (!r && e && e.__esModule) return e;
17
17
  if (null === e || ("object" != typeof e && "function" != typeof e))
18
- return { default: e };
18
+ return {
19
+ default: e,
20
+ };
19
21
  var t = _getRequireWildcardCache(r);
20
22
  if (t && t.has(e)) return t.get(e);
21
- var n = { __proto__: null },
23
+ var n = {
24
+ __proto__: null,
25
+ },
22
26
  a = Object.defineProperty && Object.getOwnPropertyDescriptor;
23
27
  for (var u in e)
24
28
  if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
@@ -28,7 +32,11 @@ function _interopRequireWildcard(e, r) {
28
32
  return (n.default = e), t && t.set(e, n), n;
29
33
  }
30
34
  function _interopRequireDefault(e) {
31
- return e && e.__esModule ? e : { default: e };
35
+ return e && e.__esModule
36
+ ? e
37
+ : {
38
+ default: e,
39
+ };
32
40
  }
33
41
  const WRAP_NAME = "$$_REQUIRE";
34
42
  const IIFE_PARAM = _template.default.expression(
@@ -40,7 +48,8 @@ function wrapModule(
40
48
  importAllName,
41
49
  dependencyMapName,
42
50
  globalPrefix,
43
- skipRequireRename
51
+ skipRequireRename,
52
+ { unstable_useStaticHermesModuleFactory = false } = {}
44
53
  ) {
45
54
  const params = buildParameters(
46
55
  importDefaultName,
@@ -48,7 +57,17 @@ function wrapModule(
48
57
  dependencyMapName
49
58
  );
50
59
  const factory = functionFromProgram(fileAst.program, params);
51
- const def = t.callExpression(t.identifier(`${globalPrefix}__d`), [factory]);
60
+ const def = t.callExpression(t.identifier(`${globalPrefix}__d`), [
61
+ unstable_useStaticHermesModuleFactory
62
+ ? t.callExpression(
63
+ t.memberExpression(
64
+ t.identifier("$SHBuiltin"),
65
+ t.identifier("moduleFactory")
66
+ ),
67
+ [t.identifier("_$$_METRO_MODULE_ID"), factory]
68
+ )
69
+ : factory,
70
+ ]);
52
71
  const ast = t.file(t.program([t.expressionStatement(def)]));
53
72
  const requireName = skipRequireRename ? "require" : renameRequires(ast);
54
73
  return {
@@ -64,17 +83,28 @@ function wrapPolyfill(fileAst) {
64
83
  function jsonToCommonJS(source) {
65
84
  return `module.exports = ${source};`;
66
85
  }
67
- function wrapJson(source, globalPrefix) {
86
+ function wrapJson(
87
+ source,
88
+ globalPrefix,
89
+ unstable_useStaticHermesModuleFactory = false
90
+ ) {
68
91
  const moduleFactoryParameters = buildParameters(
69
92
  "_importDefaultUnused",
70
93
  "_importAllUnused",
71
94
  "_dependencyMapUnused"
72
95
  );
73
- return [
74
- `${globalPrefix}__d(function(${moduleFactoryParameters.join(", ")}) {`,
96
+ const factory = [
97
+ `function(${moduleFactoryParameters.join(", ")}) {`,
75
98
  ` ${jsonToCommonJS(source)}`,
76
- "});",
99
+ "}",
77
100
  ].join("\n");
101
+ return (
102
+ `${globalPrefix}__d(` +
103
+ (unstable_useStaticHermesModuleFactory
104
+ ? "$SHBuiltin.moduleFactory(_$$_METRO_MODULE_ID, " + factory + ")"
105
+ : factory) +
106
+ ");"
107
+ );
78
108
  }
79
109
  function functionFromProgram(program, parameters) {
80
110
  return t.functionExpression(
@@ -33,6 +33,9 @@ function wrapModule(
33
33
  dependencyMapName: string,
34
34
  globalPrefix: string,
35
35
  skipRequireRename: boolean,
36
+ {
37
+ unstable_useStaticHermesModuleFactory = false,
38
+ }: $ReadOnly<{unstable_useStaticHermesModuleFactory?: boolean}> = {},
36
39
  ): {
37
40
  ast: BabelNodeFile,
38
41
  requireName: string,
@@ -43,7 +46,19 @@ function wrapModule(
43
46
  dependencyMapName,
44
47
  );
45
48
  const factory = functionFromProgram(fileAst.program, params);
46
- const def = t.callExpression(t.identifier(`${globalPrefix}__d`), [factory]);
49
+
50
+ const def = t.callExpression(t.identifier(`${globalPrefix}__d`), [
51
+ unstable_useStaticHermesModuleFactory
52
+ ? t.callExpression(
53
+ t.memberExpression(
54
+ t.identifier('$SHBuiltin'),
55
+ t.identifier('moduleFactory'),
56
+ ),
57
+ [t.identifier('_$$_METRO_MODULE_ID'), factory],
58
+ )
59
+ : factory,
60
+ ]);
61
+
47
62
  const ast = t.file(t.program([t.expressionStatement(def)]));
48
63
 
49
64
  // `require` doesn't need to be scoped when Metro serializes to iife because the local function
@@ -64,7 +79,11 @@ function jsonToCommonJS(source: string): string {
64
79
  return `module.exports = ${source};`;
65
80
  }
66
81
 
67
- function wrapJson(source: string, globalPrefix: string): string {
82
+ function wrapJson(
83
+ source: string,
84
+ globalPrefix: string,
85
+ unstable_useStaticHermesModuleFactory?: boolean = false,
86
+ ): string {
68
87
  // Unused parameters; remember that's wrapping JSON.
69
88
  const moduleFactoryParameters = buildParameters(
70
89
  '_importDefaultUnused',
@@ -72,11 +91,19 @@ function wrapJson(source: string, globalPrefix: string): string {
72
91
  '_dependencyMapUnused',
73
92
  );
74
93
 
75
- return [
76
- `${globalPrefix}__d(function(${moduleFactoryParameters.join(', ')}) {`,
94
+ const factory = [
95
+ `function(${moduleFactoryParameters.join(', ')}) {`,
77
96
  ` ${jsonToCommonJS(source)}`,
78
- '});',
97
+ '}',
79
98
  ].join('\n');
99
+
100
+ return (
101
+ `${globalPrefix}__d(` +
102
+ (unstable_useStaticHermesModuleFactory
103
+ ? '$SHBuiltin.moduleFactory(_$$_METRO_MODULE_ID, ' + factory + ')'
104
+ : factory) +
105
+ ');'
106
+ );
80
107
  }
81
108
 
82
109
  function functionFromProgram(
@@ -15,7 +15,7 @@ import type {CallExpression, Identifier, StringLiteral} from '@babel/types';
15
15
  import type {
16
16
  AllowOptionalDependencies,
17
17
  AsyncDependencyType,
18
- } from 'metro/src/DeltaBundler/types.flow.js';
18
+ } from 'metro/private/DeltaBundler/types.flow';
19
19
 
20
20
  import {isProgram} from '@babel/types';
21
21
 
@@ -766,6 +766,8 @@ const DefaultDependencyTransformer: DependencyTransformer = {
766
766
  ? {MODULE_NAME: createModuleNameLiteral(dependency)}
767
767
  : null),
768
768
  };
769
+ /* $FlowFixMe[incompatible-call] Natural Inference rollout. See
770
+ * https://fburl.com/gdoc/y8dn025u */
769
771
  path.replaceWith(makeNode(opts));
770
772
  },
771
773
 
@@ -787,6 +789,8 @@ const DefaultDependencyTransformer: DependencyTransformer = {
787
789
  ? {MODULE_NAME: createModuleNameLiteral(dependency)}
788
790
  : null),
789
791
  };
792
+ /* $FlowFixMe[incompatible-call] Natural Inference rollout. See
793
+ * https://fburl.com/gdoc/y8dn025u */
790
794
  path.replaceWith(makeNode(opts));
791
795
  },
792
796
 
@@ -808,6 +812,8 @@ const DefaultDependencyTransformer: DependencyTransformer = {
808
812
  ? {MODULE_NAME: createModuleNameLiteral(dependency)}
809
813
  : null),
810
814
  };
815
+ /* $FlowFixMe[incompatible-call] Natural Inference rollout. See
816
+ * https://fburl.com/gdoc/y8dn025u */
811
817
  path.replaceWith(makeNode(opts));
812
818
  },
813
819
 
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
 
3
- const { greatestLowerBound } = require("metro-source-map/src/Consumer/search");
3
+ const {
4
+ greatestLowerBound,
5
+ } = require("metro-source-map/private/Consumer/search");
4
6
  const {
5
7
  SourceMetadataMapConsumer,
6
- } = require("metro-symbolicate/src/Symbolication");
8
+ } = require("metro-symbolicate/private/Symbolication");
7
9
  function createFunctionNameGetter(module) {
8
10
  const consumer = new SourceMetadataMapConsumer(
9
11
  {
@@ -17,10 +17,12 @@ import type {
17
17
  import type {ExplodedSourceMap} from '../DeltaBundler/Serializers/getExplodedSourceMap';
18
18
  import type {ConfigT} from 'metro-config';
19
19
 
20
- const {greatestLowerBound} = require('metro-source-map/src/Consumer/search');
20
+ const {
21
+ greatestLowerBound,
22
+ } = require('metro-source-map/private/Consumer/search');
21
23
  const {
22
24
  SourceMetadataMapConsumer,
23
- } = require('metro-symbolicate/src/Symbolication');
25
+ } = require('metro-symbolicate/private/Symbolication');
24
26
 
25
27
  export type StackFrameInput = {
26
28
  +file: ?string,
package/src/Server.d.ts CHANGED
@@ -13,6 +13,7 @@ import type {RamBundleInfo} from './DeltaBundler/Serializers/getRamBundleInfo';
13
13
  import type {GraphId} from './lib/getGraphId';
14
14
  import type MultipartResponse from './Server/MultipartResponse';
15
15
  import type {
16
+ BuildOptions,
16
17
  BundleOptions,
17
18
  GraphOptions,
18
19
  SplitBundleOptions,
@@ -94,9 +95,13 @@ export default class Server {
94
95
  end(): void;
95
96
  getBundler(): IncrementalBundler;
96
97
  getCreateModuleId(): (path: string) => number;
97
- build(options: BundleOptions): Promise<{
98
+ build(
99
+ bundleOptions: BundleOptions,
100
+ buildOptions?: BuildOptions,
101
+ ): Promise<{
98
102
  code: string;
99
103
  map: string;
104
+ assets?: ReadonlyArray<AssetData>;
100
105
  }>;
101
106
  getRamBundleInfo(options: BundleOptions): Promise<RamBundleInfo>;
102
107
  getAssets(options: BundleOptions): Promise<ReadonlyArray<AssetData>>;
package/src/Server.js CHANGED
@@ -100,25 +100,14 @@ class Server {
100
100
  getCreateModuleId() {
101
101
  return this._createModuleId;
102
102
  }
103
- async build(options) {
103
+ async _serializeGraph({ splitOptions, prepend, graph }) {
104
104
  const {
105
105
  entryFile,
106
106
  graphOptions,
107
- onProgress,
108
107
  resolverOptions,
109
108
  serializerOptions,
110
109
  transformOptions,
111
- } = splitBundleOptions(options);
112
- const { prepend, graph } = await this._bundler.buildGraph(
113
- entryFile,
114
- transformOptions,
115
- resolverOptions,
116
- {
117
- onProgress,
118
- shallow: graphOptions.shallow,
119
- lazy: graphOptions.lazy,
120
- }
121
- );
110
+ } = splitOptions;
122
111
  const entryPoint = this._getEntryPointAbsolutePath(entryFile);
123
112
  const bundleOptions = {
124
113
  asyncRequireModulePath: await this._resolveRelativePath(
@@ -188,6 +177,48 @@ class Server {
188
177
  map: bundleMap,
189
178
  };
190
179
  }
180
+ async build(bundleOptions, { withAssets } = {}) {
181
+ const splitOptions = splitBundleOptions(bundleOptions);
182
+ const {
183
+ entryFile,
184
+ graphOptions,
185
+ onProgress,
186
+ resolverOptions,
187
+ transformOptions,
188
+ } = splitOptions;
189
+ const { prepend, graph } = await this._bundler.buildGraph(
190
+ entryFile,
191
+ transformOptions,
192
+ resolverOptions,
193
+ {
194
+ onProgress,
195
+ shallow: graphOptions.shallow,
196
+ lazy: graphOptions.lazy,
197
+ }
198
+ );
199
+ const [{ code, map }, assets] = await Promise.all([
200
+ this._serializeGraph({
201
+ splitOptions,
202
+ prepend,
203
+ graph,
204
+ }),
205
+ withAssets
206
+ ? this._getAssetsFromDependencies(
207
+ graph.dependencies,
208
+ bundleOptions.platform
209
+ )
210
+ : null,
211
+ ]);
212
+ return {
213
+ code,
214
+ map,
215
+ ...(withAssets
216
+ ? {
217
+ assets: nullthrows(assets),
218
+ }
219
+ : null),
220
+ };
221
+ }
191
222
  async getRamBundleInfo(options) {
192
223
  const {
193
224
  entryFile,
@@ -256,10 +287,16 @@ class Server {
256
287
  lazy: false,
257
288
  }
258
289
  );
290
+ return this._getAssetsFromDependencies(
291
+ dependencies,
292
+ transformOptions.platform
293
+ );
294
+ }
295
+ async _getAssetsFromDependencies(dependencies, platform) {
259
296
  return await getAssets(dependencies, {
260
297
  processModuleFilter: this._config.serializer.processModuleFilter,
261
298
  assetPlugins: this._config.transformer.assetPlugins,
262
- platform: transformOptions.platform,
299
+ platform,
263
300
  projectRoot: this._getServerRootDir(),
264
301
  publicPath: this._config.transformer.publicPath,
265
302
  });
@@ -17,6 +17,7 @@ import type {RamBundleInfo} from './DeltaBundler/Serializers/getRamBundleInfo';
17
17
  import type {
18
18
  MixedOutput,
19
19
  Module,
20
+ ReadOnlyDependencies,
20
21
  ReadOnlyGraph,
21
22
  TransformInputOptions,
22
23
  TransformResult,
@@ -26,6 +27,7 @@ import type {GraphId} from './lib/getGraphId';
26
27
  import type {Reporter} from './lib/reporting';
27
28
  import type {StackFrameInput, StackFrameOutput} from './Server/symbolicate';
28
29
  import type {
30
+ BuildOptions,
29
31
  BundleOptions,
30
32
  GraphOptions,
31
33
  ResolverInputOptions,
@@ -38,8 +40,8 @@ import type {ConfigT, RootPerfLogger} from 'metro-config';
38
40
  import type {
39
41
  ActionLogEntryData,
40
42
  ActionStartLogEntry,
41
- } from 'metro-core/src/Logger';
42
- import type {CustomResolverOptions} from 'metro-resolver/src/types';
43
+ } from 'metro-core/private/Logger';
44
+ import type {CustomResolverOptions} from 'metro-resolver/private/types';
43
45
  import type {CustomTransformOptions} from 'metro-transform-worker';
44
46
 
45
47
  import {SourcePathsMode} from './shared/types.flow';
@@ -211,30 +213,22 @@ class Server {
211
213
  return this._createModuleId;
212
214
  }
213
215
 
214
- async build(options: BundleOptions): Promise<{
215
- code: string,
216
- map: string,
217
- ...
218
- }> {
216
+ async _serializeGraph({
217
+ splitOptions,
218
+ prepend,
219
+ graph,
220
+ }: $ReadOnly<{
221
+ splitOptions: SplitBundleOptions,
222
+ prepend: $ReadOnlyArray<Module<>>,
223
+ graph: ReadOnlyGraph<>,
224
+ }>): Promise<{code: string, map: string}> {
219
225
  const {
220
226
  entryFile,
221
227
  graphOptions,
222
- onProgress,
223
228
  resolverOptions,
224
229
  serializerOptions,
225
230
  transformOptions,
226
- } = splitBundleOptions(options);
227
-
228
- const {prepend, graph} = await this._bundler.buildGraph(
229
- entryFile,
230
- transformOptions,
231
- resolverOptions,
232
- {
233
- onProgress,
234
- shallow: graphOptions.shallow,
235
- lazy: graphOptions.lazy,
236
- },
237
- );
231
+ } = splitOptions;
238
232
 
239
233
  const entryPoint = this._getEntryPointAbsolutePath(entryFile);
240
234
 
@@ -307,6 +301,56 @@ class Server {
307
301
  };
308
302
  }
309
303
 
304
+ async build(
305
+ bundleOptions: BundleOptions,
306
+ {withAssets}: BuildOptions = {},
307
+ ): Promise<{
308
+ code: string,
309
+ map: string,
310
+ assets?: $ReadOnlyArray<AssetData>,
311
+ ...
312
+ }> {
313
+ const splitOptions = splitBundleOptions(bundleOptions);
314
+ const {
315
+ entryFile,
316
+ graphOptions,
317
+ onProgress,
318
+ resolverOptions,
319
+ transformOptions,
320
+ } = splitOptions;
321
+
322
+ const {prepend, graph} = await this._bundler.buildGraph(
323
+ entryFile,
324
+ transformOptions,
325
+ resolverOptions,
326
+ {
327
+ onProgress,
328
+ shallow: graphOptions.shallow,
329
+ lazy: graphOptions.lazy,
330
+ },
331
+ );
332
+
333
+ const [{code, map}, assets] = await Promise.all([
334
+ this._serializeGraph({
335
+ splitOptions,
336
+ prepend,
337
+ graph,
338
+ }),
339
+ withAssets
340
+ ? this._getAssetsFromDependencies(
341
+ graph.dependencies,
342
+ bundleOptions.platform,
343
+ )
344
+ : null,
345
+ ]);
346
+
347
+ return {
348
+ code,
349
+ map,
350
+ ...(withAssets ? {assets: nullthrows(assets)} : null),
351
+ };
352
+ }
353
+
310
354
  async getRamBundleInfo(options: BundleOptions): Promise<RamBundleInfo> {
311
355
  const {
312
356
  entryFile,
@@ -377,10 +421,20 @@ class Server {
377
421
  {onProgress, shallow: false, lazy: false},
378
422
  );
379
423
 
424
+ return this._getAssetsFromDependencies(
425
+ dependencies,
426
+ transformOptions.platform,
427
+ );
428
+ }
429
+
430
+ async _getAssetsFromDependencies(
431
+ dependencies: ReadOnlyDependencies<>,
432
+ platform: ?string,
433
+ ): Promise<$ReadOnlyArray<AssetData>> {
380
434
  return await getAssets(dependencies, {
381
435
  processModuleFilter: this._config.serializer.processModuleFilter,
382
436
  assetPlugins: this._config.transformer.assetPlugins,
383
- platform: transformOptions.platform,
437
+ platform,
384
438
  projectRoot: this._getServerRootDir(),
385
439
  publicPath: this._config.transformer.publicPath,
386
440
  });
@@ -4,7 +4,11 @@ var _parseKeyValueParamArray = _interopRequireDefault(
4
4
  require("../cli/parseKeyValueParamArray")
5
5
  );
6
6
  function _interopRequireDefault(e) {
7
- return e && e.__esModule ? e : { default: e };
7
+ return e && e.__esModule
8
+ ? e
9
+ : {
10
+ default: e,
11
+ };
8
12
  }
9
13
  const { makeAsyncCommand } = require("../cli-utils");
10
14
  const TerminalReporter = require("../lib/TerminalReporter");
@@ -84,7 +84,10 @@ module.exports = () => ({
84
84
  resetCache: _resetCache,
85
85
  ...runServerOptions
86
86
  } = argv;
87
- server = await MetroApi.runServer(config, runServerOptions);
87
+ ({ httpServer: server } = await MetroApi.runServer(
88
+ config,
89
+ runServerOptions
90
+ ));
88
91
  restarting = false;
89
92
  }
90
93
  const foundConfig = await resolveConfig(argv.config);
@@ -107,7 +107,10 @@ module.exports = (): {
107
107
  resetCache: _resetCache,
108
108
  ...runServerOptions
109
109
  } = argv;
110
- server = await MetroApi.runServer(config, runServerOptions);
110
+ ({httpServer: server} = await MetroApi.runServer(
111
+ config,
112
+ runServerOptions,
113
+ ));
111
114
 
112
115
  restarting = false;
113
116
  }