metro 0.63.0 → 0.64.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 (90) hide show
  1. package/package.json +22 -22
  2. package/src/Assets.js +8 -2
  3. package/src/Bundler/util.js +17 -10
  4. package/src/Bundler/util.js.flow +13 -12
  5. package/src/Bundler.js +4 -0
  6. package/src/DeltaBundler/DeltaCalculator.js +6 -1
  7. package/src/DeltaBundler/Serializers/baseBytecodeBundle.js +10 -0
  8. package/src/DeltaBundler/Serializers/baseJSBundle.js +5 -0
  9. package/src/DeltaBundler/Serializers/getAllFiles.js +6 -0
  10. package/src/DeltaBundler/Serializers/getAssets.js +4 -0
  11. package/src/DeltaBundler/Serializers/getRamBundleInfo.js +6 -0
  12. package/src/DeltaBundler/Serializers/helpers/bytecode.js +5 -0
  13. package/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js +5 -0
  14. package/src/DeltaBundler/Serializers/helpers/processBytecodeModules.js +2 -0
  15. package/src/DeltaBundler/Serializers/helpers/processModules.js +2 -0
  16. package/src/DeltaBundler/Serializers/hmrJSBundle.js +8 -2
  17. package/src/DeltaBundler/Serializers/sourceMapGenerator.js +4 -0
  18. package/src/DeltaBundler/Serializers/sourceMapObject.js +4 -0
  19. package/src/DeltaBundler/Transformer.js +16 -0
  20. package/src/DeltaBundler/Worker.js +4 -0
  21. package/src/DeltaBundler/WorkerFarm.js +9 -0
  22. package/src/DeltaBundler/computeDelta.js +5 -0
  23. package/src/DeltaBundler/getTransformCacheKey.js +1 -1
  24. package/src/DeltaBundler/mergeDeltas.js +5 -0
  25. package/src/DeltaBundler/traverseDependencies.js +14 -0
  26. package/src/DeltaBundler.js +6 -1
  27. package/src/HmrServer.js +18 -0
  28. package/src/IncrementalBundler.js +16 -0
  29. package/src/ModuleGraph/node-haste/Package.js +5 -0
  30. package/src/ModuleGraph/node-haste/node-haste.flow.js.flow +0 -2
  31. package/src/ModuleGraph/node-haste/node-haste.js +3 -0
  32. package/src/ModuleGraph/node-haste/node-haste.js.flow +4 -2
  33. package/src/ModuleGraph/output/indexed-ram-bundle.js +10 -0
  34. package/src/ModuleGraph/output/multiple-files-ram-bundle.js +10 -0
  35. package/src/ModuleGraph/output/reverse-dependency-map-references.js +33 -9
  36. package/src/ModuleGraph/output/reverse-dependency-map-references.js.flow +28 -13
  37. package/src/ModuleGraph/output/util.js +59 -25
  38. package/src/ModuleGraph/output/util.js.flow +59 -23
  39. package/src/ModuleGraph/test-helpers.js +74 -2
  40. package/src/ModuleGraph/types.flow.js.flow +13 -8
  41. package/src/ModuleGraph/worker/JsFileWrapping.js +90 -12
  42. package/src/ModuleGraph/worker/JsFileWrapping.js.flow +34 -20
  43. package/src/ModuleGraph/worker/collectDependencies.js +329 -205
  44. package/src/ModuleGraph/worker/collectDependencies.js.flow +397 -209
  45. package/src/ModuleGraph/worker/generate.js.flow +2 -2
  46. package/src/ModuleGraph/worker/generateImportNames.js +2 -1
  47. package/src/ModuleGraph/worker/generateImportNames.js.flow +3 -4
  48. package/src/ModuleGraph/worker/mergeSourceMaps.js +5 -0
  49. package/src/Server/symbolicate.js +14 -0
  50. package/src/Server.js +16 -3
  51. package/src/Server.js.flow +1 -0
  52. package/src/cli-utils.js +4 -0
  53. package/src/cli.js +0 -0
  54. package/src/commands/build.js +10 -0
  55. package/src/commands/build.js.flow +2 -0
  56. package/src/commands/dependencies.js +4 -0
  57. package/src/commands/serve.js +5 -0
  58. package/src/commands/serve.js.flow +2 -0
  59. package/src/index.js +13 -1
  60. package/src/index.js.flow +2 -0
  61. package/src/integration_tests/basic_bundle/import-export/index.js +19 -2
  62. package/src/integration_tests/execBundle.js +2 -2
  63. package/src/integration_tests/metro.config.js +4 -0
  64. package/src/lib/BatchProcessor.js +1 -1
  65. package/src/lib/TerminalReporter.js +10 -0
  66. package/src/lib/attachWebsocketServer.js +5 -1
  67. package/src/lib/bundleToBytecode.js +7 -3
  68. package/src/lib/bundleToString.js +6 -1
  69. package/src/lib/debounceAsyncQueue.js +4 -0
  70. package/src/lib/getAppendScripts.js +2 -0
  71. package/src/lib/getPreludeCode.js +2 -0
  72. package/src/lib/getPrependedScripts.js +11 -0
  73. package/src/lib/logToConsole.js +1 -2
  74. package/src/lib/parseOptionsFromUrl.js +5 -0
  75. package/src/lib/reporting.js +1 -1
  76. package/src/lib/splitBundleOptions.js +1 -1
  77. package/src/lib/transformHelpers.js +19 -3
  78. package/src/lib/transformHelpers.js.flow +4 -4
  79. package/src/node-haste/DependencyGraph/ModuleResolution.js +10 -2
  80. package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +6 -5
  81. package/src/node-haste/DependencyGraph.js +11 -2
  82. package/src/node-haste/DependencyGraph.js.flow +5 -0
  83. package/src/node-haste/Package.js +2 -0
  84. package/src/shared/output/RamBundle/as-assets.js +1 -2
  85. package/src/shared/output/RamBundle/as-indexed-file.js +2 -0
  86. package/src/shared/output/RamBundle/util.js +2 -2
  87. package/src/shared/output/RamBundle.js +9 -0
  88. package/src/shared/output/bundle.js +9 -0
  89. package/src/ModuleGraph/worker/optimizeDependencies.js +0 -122
  90. package/src/ModuleGraph/worker/optimizeDependencies.js.flow +0 -128
@@ -55,17 +55,24 @@ function addModuleIdsToModuleWrapper(
55
55
 
56
56
  exports.addModuleIdsToModuleWrapper = addModuleIdsToModuleWrapper;
57
57
 
58
+ type InlineModuleIdsOptions = {
59
+ dependencyMapReservedName: ?string,
60
+ globalPrefix: string,
61
+ ignoreMissingDependencyMapReference?: boolean,
62
+ };
63
+
58
64
  function inlineModuleIds(
59
65
  module: Module,
60
66
  idForPath: ({path: string, ...}) => number,
61
67
  {
62
68
  dependencyMapReservedName = undefined,
63
69
  globalPrefix,
64
- }: {dependencyMapReservedName: ?string, globalPrefix: string} = {},
70
+ ignoreMissingDependencyMapReference = false,
71
+ }: InlineModuleIdsOptions,
65
72
  ): {
66
73
  moduleCode: string,
67
74
  moduleMap: ?BasicSourceMap,
68
- ...
75
+ fileId: number,
69
76
  } {
70
77
  const {dependencies, file} = module;
71
78
  const {code, map, path} = file;
@@ -78,7 +85,7 @@ function inlineModuleIds(
78
85
 
79
86
  if (!dependencyIds.length) {
80
87
  // Nothing to inline in this module.
81
- return {moduleCode: addParamsToDefineCall(code, fileId), moduleMap: map};
88
+ return {fileId, moduleCode: code, moduleMap: map};
82
89
  }
83
90
 
84
91
  if (dependencyMapReservedName != null) {
@@ -108,6 +115,10 @@ function inlineModuleIds(
108
115
  * integer printed as a simple sequence of digits.
109
116
  */
110
117
  if (!code.includes(dependencyMapReservedName)) {
118
+ if (ignoreMissingDependencyMapReference) {
119
+ return {fileId, moduleCode: code, moduleMap: map};
120
+ }
121
+
111
122
  // If we're here, the module was probably generated by some code that
112
123
  // doesn't make the dependency map name externally configurable, or a
113
124
  // mock that needs to be updated.
@@ -136,35 +147,57 @@ function inlineModuleIds(
136
147
  },
137
148
  );
138
149
  return {
139
- moduleCode: addParamsToDefineCall(inlinedCode, fileId),
150
+ fileId,
151
+ moduleCode: inlinedCode,
140
152
  moduleMap: map,
141
153
  };
142
154
  }
143
- const {ast} = transformSync(code, {
144
- ast: true,
145
- babelrc: false,
146
- code: false,
147
- configFile: false,
148
- plugins: [
149
- ...passthroughSyntaxPlugins,
150
- [reverseDependencyMapReferences, {dependencyIds, globalPrefix}],
151
- ],
152
- });
155
+ const ast = nullthrows(
156
+ transformSync(code, {
157
+ ast: true,
158
+ babelrc: false,
159
+ code: false,
160
+ configFile: false,
161
+ plugins: [
162
+ ...passthroughSyntaxPlugins,
163
+ [reverseDependencyMapReferences, {dependencyIds, globalPrefix}],
164
+ ],
165
+ }).ast,
166
+ );
153
167
 
154
168
  const {code: generatedCode, map: generatedMap} = generate(ast, path, '');
155
169
 
156
170
  return {
157
- moduleCode: addParamsToDefineCall(generatedCode, fileId),
171
+ fileId,
172
+ moduleCode: generatedCode,
158
173
  moduleMap: map && generatedMap && mergeSourceMaps(path, map, generatedMap),
159
174
  };
160
175
  }
161
176
 
162
- function escapeRegex(str: string): string {
163
- // From http://stackoverflow.com/questions/14076210/
164
- return str.replace(/([.?*+\^$\[\]\\(){}|\-])/g, '\\$1');
177
+ function inlineModuleIdsAndAddParamsToDefineCall(
178
+ module: Module,
179
+ idForPath: ({path: string, ...}) => number,
180
+ options: InlineModuleIdsOptions,
181
+ ): {
182
+ moduleCode: string,
183
+ moduleMap: ?BasicSourceMap,
184
+ } {
185
+ const {fileId, moduleCode, moduleMap} = inlineModuleIds(
186
+ module,
187
+ idForPath,
188
+ options,
189
+ );
190
+
191
+ return {moduleCode: addParamsToDefineCall(moduleCode, fileId), moduleMap};
165
192
  }
166
193
 
167
194
  exports.inlineModuleIds = inlineModuleIds;
195
+ exports.inlineModuleIdsAndAddParamsToDefineCall = inlineModuleIdsAndAddParamsToDefineCall;
196
+
197
+ function escapeRegex(str: string): string {
198
+ // From http://stackoverflow.com/questions/14076210/
199
+ return str.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
200
+ }
168
201
 
169
202
  type IdForPathFn = ({path: string, ...}) => number;
170
203
 
@@ -180,7 +213,6 @@ function getModuleCodeAndMap(
180
213
  enableIDInlining: boolean,
181
214
  dependencyMapReservedName: ?string,
182
215
  globalPrefix: string,
183
- ...
184
216
  }>,
185
217
  ): {|
186
218
  moduleCode: string,
@@ -196,10 +228,14 @@ function getModuleCodeAndMap(
196
228
  moduleCode = addModuleIdsToModuleWrapper(module, idForPath);
197
229
  moduleMap = file.map;
198
230
  } else {
199
- ({moduleCode, moduleMap} = inlineModuleIds(module, idForPath, {
200
- dependencyMapReservedName: options.dependencyMapReservedName,
201
- globalPrefix: options.globalPrefix,
202
- }));
231
+ ({moduleCode, moduleMap} = inlineModuleIdsAndAddParamsToDefineCall(
232
+ module,
233
+ idForPath,
234
+ {
235
+ dependencyMapReservedName: options.dependencyMapReservedName,
236
+ globalPrefix: options.globalPrefix,
237
+ },
238
+ ));
203
239
  }
204
240
  if (moduleMap && moduleMap.sources) {
205
241
  const x_facebook_sources = [];
@@ -10,11 +10,83 @@
10
10
 
11
11
  const generate = require("@babel/generator").default;
12
12
 
13
+ const _require = require("jest-snapshot"),
14
+ toMatchSnapshot = _require.toMatchSnapshot;
15
+
13
16
  const generateOptions = {
14
17
  concise: true,
15
18
  sourceType: "module"
16
19
  };
17
20
 
18
- exports.codeFromAst = ast => generate(ast, generateOptions).code;
21
+ const codeFromAst = ast => generate(ast, generateOptions).code;
22
+
23
+ const comparableCode = code => code.trim().replace(/\s+/g, " ");
24
+
25
+ function toEqualComparableCode(received, expected) {
26
+ const comparableExpected = comparableCode(expected);
27
+ const pass = received === comparableExpected;
28
+ const options = {
29
+ isNot: this.isNot,
30
+ promise: this.promise
31
+ };
32
+ const message = pass
33
+ ? () =>
34
+ this.utils.matcherHint(
35
+ "toEqualComparableCode",
36
+ undefined,
37
+ undefined,
38
+ options
39
+ ) +
40
+ "\n\n" +
41
+ `Expected: not ${this.utils.printExpected(comparableExpected)}\n` +
42
+ `Received: ${this.utils.printReceived(received)}`
43
+ : () => {
44
+ const diffString = this.utils.printDiffOrStringify(
45
+ comparableExpected,
46
+ received,
47
+ "expected",
48
+ "received",
49
+ this.expand
50
+ );
51
+ return (
52
+ this.utils.matcherHint(
53
+ "toEqualComparableCode",
54
+ undefined,
55
+ undefined,
56
+ options
57
+ ) +
58
+ "\n\n" +
59
+ diffString
60
+ );
61
+ };
62
+ return {
63
+ actual: received,
64
+ message,
65
+ pass
66
+ };
67
+ } // See https://superuser.com/questions/380772/removing-ansi-color-codes-from-text-stream
19
68
 
20
- exports.comparableCode = code => code.trim().replace(/\s+/g, " ");
69
+ const ANSI_PATTERN = /\x1b\[[0-9;]*m/g;
70
+
71
+ function trimANSICodes(input) {
72
+ return input.replace(ANSI_PATTERN, "");
73
+ }
74
+ /**
75
+ * Matches a text that contains ANSI control codes (e.g. [39m^) against a snapshot.
76
+ * Usage: Call expect.extend({toMatchCodeFrameSnapshot}) to add the matcher in your test
77
+ */
78
+
79
+ function toMatchCodeFrameSnapshot(received) {
80
+ return toMatchSnapshot.call(
81
+ this,
82
+ trimANSICodes(received),
83
+ "toMatchCodeFrameSnapshot"
84
+ );
85
+ }
86
+
87
+ module.exports = {
88
+ codeFromAst,
89
+ comparableCode,
90
+ toEqualComparableCode,
91
+ toMatchCodeFrameSnapshot
92
+ };
@@ -23,6 +23,7 @@ export type Callback<A = void, B = void> = (Error => void) &
23
23
  ((null | void, A, B) => void);
24
24
 
25
25
  export type Dependency = {|
26
+ // The module name or path used to require the dependency
26
27
  id: string,
27
28
  +isAsync: boolean,
28
29
  +isPrefetchOnly: boolean,
@@ -128,29 +129,33 @@ export type ResolveFn = (id: string, source: ?string) => string;
128
129
 
129
130
  export type TransformResult = ConcreteTransformResult | LinkedTransformResult;
130
131
 
132
+ export type ImportNames = {
133
+ all: string,
134
+ default: string,
135
+ };
136
+
131
137
  export type ConcreteTransformResult = {
138
+ type: 'concrete',
132
139
  code: string,
133
140
  dependencies: $ReadOnlyArray<TransformResultDependency>,
134
141
  dependencyMapName?: string,
135
142
  map: ?BasicSourceMap,
136
143
  requireName: string,
137
144
  soundResources?: ?Array<string>,
138
- importNames?: {
139
- all: string,
140
- default: string,
141
- ...
142
- },
145
+ importNames?: ImportNames,
143
146
  isESModule?: true,
144
147
  };
145
148
 
146
- export type LinkedTransformResult = $ReadOnly<{sourceVariantName: string}>;
149
+ export type LinkedTransformResult = $ReadOnly<{
150
+ type: 'linked',
151
+ sourceVariantName: string,
152
+ }>;
147
153
 
148
154
  export type TransformResults = {
149
155
  +[string]: TransformResult,
150
- ...,
151
156
  };
152
157
 
153
- export type TransformVariants = {+[name: string]: {...}, ...};
158
+ export type TransformVariants = {+[name: string]: {...}};
154
159
 
155
160
  export type TransformedCodeFile = {|
156
161
  +file: string,
@@ -9,18 +9,83 @@
9
9
  */
10
10
  "use strict";
11
11
 
12
- const t = require("@babel/types");
12
+ var _template = _interopRequireDefault(require("@babel/template"));
13
13
 
14
- const template = require("@babel/template").default;
14
+ var _traverse = _interopRequireDefault(require("@babel/traverse"));
15
15
 
16
- const traverse = require("@babel/traverse").default;
16
+ var t = _interopRequireWildcard(require("@babel/types"));
17
+
18
+ var _invariant = _interopRequireDefault(require("invariant"));
19
+
20
+ function _getRequireWildcardCache() {
21
+ if (typeof WeakMap !== "function") return null;
22
+ var cache = new WeakMap();
23
+
24
+ _getRequireWildcardCache = function() {
25
+ return cache;
26
+ };
27
+
28
+ return cache;
29
+ }
30
+
31
+ function _interopRequireWildcard(obj) {
32
+ if (obj && obj.__esModule) {
33
+ return obj;
34
+ }
35
+
36
+ if (obj === null || (typeof obj !== "object" && typeof obj !== "function")) {
37
+ return {
38
+ default: obj
39
+ };
40
+ }
41
+
42
+ var cache = _getRequireWildcardCache();
43
+
44
+ if (cache && cache.has(obj)) {
45
+ return cache.get(obj);
46
+ }
47
+
48
+ var newObj = {};
49
+ var hasPropertyDescriptor =
50
+ Object.defineProperty && Object.getOwnPropertyDescriptor;
51
+
52
+ for (var key in obj) {
53
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
54
+ var desc = hasPropertyDescriptor
55
+ ? Object.getOwnPropertyDescriptor(obj, key)
56
+ : null;
57
+
58
+ if (desc && (desc.get || desc.set)) {
59
+ Object.defineProperty(newObj, key, desc);
60
+ } else {
61
+ newObj[key] = obj[key];
62
+ }
63
+ }
64
+ }
65
+
66
+ newObj.default = obj;
67
+
68
+ if (cache) {
69
+ cache.set(obj, newObj);
70
+ }
71
+
72
+ return newObj;
73
+ }
74
+
75
+ function _interopRequireDefault(obj) {
76
+ return obj && obj.__esModule
77
+ ? obj
78
+ : {
79
+ default: obj
80
+ };
81
+ }
17
82
 
18
83
  const WRAP_NAME = "$$_REQUIRE"; // note: babel will prefix this with _
19
84
  // Check first the `global` variable as the global object. This way serializers
20
85
  // can create a local variable called global to fake it as a global object
21
86
  // without having to pollute the window object on web.
22
87
 
23
- const IIFE_PARAM = template(
88
+ const IIFE_PARAM = _template.default.expression(
24
89
  "typeof globalThis !== 'undefined' ? globalThis : typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this"
25
90
  );
26
91
 
@@ -48,27 +113,31 @@ function wrapModule(
48
113
 
49
114
  function wrapPolyfill(fileAst) {
50
115
  const factory = functionFromProgram(fileAst.program, ["global"]);
51
- const iife = t.callExpression(factory, [IIFE_PARAM().expression]);
116
+ const iife = t.callExpression(factory, [IIFE_PARAM()]);
52
117
  return t.file(t.program([t.expressionStatement(iife)]));
53
118
  }
54
119
 
120
+ function jsonToCommonJS(source) {
121
+ return `module.exports = ${source};`;
122
+ }
123
+
55
124
  function wrapJson(source, globalPrefix) {
56
125
  // Unused parameters; remember that's wrapping JSON.
57
126
  const moduleFactoryParameters = buildParameters(
58
- "_aUnused",
59
- "_bUnused",
60
- "_cUnused"
127
+ "_importDefaultUnused",
128
+ "_importAllUnused",
129
+ "_dependencyMapUnused"
61
130
  );
62
131
  return [
63
132
  `${globalPrefix}__d(function(${moduleFactoryParameters.join(", ")}) {`,
64
- ` module.exports = ${source};`,
133
+ ` ${jsonToCommonJS(source)}`,
65
134
  "});"
66
135
  ].join("\n");
67
136
  }
68
137
 
69
138
  function functionFromProgram(program, parameters) {
70
139
  return t.functionExpression(
71
- t.identifier(""),
140
+ undefined,
72
141
  parameters.map(makeIdentifier),
73
142
  t.blockStatement(program.body, program.directives)
74
143
  );
@@ -88,13 +157,21 @@ function buildParameters(importDefaultName, importAllName, dependencyMapName) {
88
157
  "exports",
89
158
  dependencyMapName
90
159
  ];
91
- }
160
+ } // Renaming requires should ideally only be done when generating for the target
161
+ // that expects the custom require name in the optimize step.
162
+ // This visitor currently renames all `require` references even if the module
163
+ // contains a custom `require` declaration. This should be fixed by only renaming
164
+ // if the `require` symbol hasn't been redeclared.
92
165
 
93
166
  function renameRequires(ast) {
94
167
  let newRequireName = WRAP_NAME;
95
- traverse(ast, {
168
+ (0, _traverse.default)(ast, {
96
169
  Program(path) {
97
170
  const body = path.get("body.0.expression.arguments.0.body");
171
+ (0, _invariant.default)(
172
+ !Array.isArray(body),
173
+ "metro: Expected `body` to be a single path."
174
+ );
98
175
  newRequireName = body.scope.generateUid(WRAP_NAME);
99
176
  body.scope.rename("require", newRequireName);
100
177
  }
@@ -105,6 +182,7 @@ function renameRequires(ast) {
105
182
  module.exports = {
106
183
  WRAP_NAME,
107
184
  wrapJson,
185
+ jsonToCommonJS,
108
186
  wrapModule,
109
187
  wrapPolyfill
110
188
  };
@@ -10,31 +10,30 @@
10
10
 
11
11
  'use strict';
12
12
 
13
- const t = require('@babel/types');
14
- const template = require('@babel/template').default;
15
- const traverse = require('@babel/traverse').default;
16
-
17
- import type {Ast} from '@babel/core';
13
+ import template from '@babel/template';
14
+ import traverse from '@babel/traverse';
15
+ import * as t from '@babel/types';
16
+ import type {Program, FunctionExpression, Identifier} from '@babel/types';
17
+ import invariant from 'invariant';
18
18
 
19
19
  const WRAP_NAME = '$$_REQUIRE'; // note: babel will prefix this with _
20
20
 
21
21
  // Check first the `global` variable as the global object. This way serializers
22
22
  // can create a local variable called global to fake it as a global object
23
23
  // without having to pollute the window object on web.
24
- const IIFE_PARAM = template(
24
+ const IIFE_PARAM = template.expression(
25
25
  "typeof globalThis !== 'undefined' ? globalThis : typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this",
26
26
  );
27
27
 
28
28
  function wrapModule(
29
- fileAst: Ast,
29
+ fileAst: BabelNodeFile,
30
30
  importDefaultName: string,
31
31
  importAllName: string,
32
32
  dependencyMapName: string,
33
33
  globalPrefix: string,
34
34
  ): {
35
- ast: Ast,
35
+ ast: BabelNodeFile,
36
36
  requireName: string,
37
- ...
38
37
  } {
39
38
  const params = buildParameters(
40
39
  importDefaultName,
@@ -50,40 +49,44 @@ function wrapModule(
50
49
  return {ast, requireName};
51
50
  }
52
51
 
53
- function wrapPolyfill(fileAst: Ast): Ast {
52
+ function wrapPolyfill(fileAst: BabelNodeFile): BabelNodeFile {
54
53
  const factory = functionFromProgram(fileAst.program, ['global']);
55
54
 
56
- const iife = t.callExpression(factory, [IIFE_PARAM().expression]);
55
+ const iife = t.callExpression(factory, [IIFE_PARAM()]);
57
56
  return t.file(t.program([t.expressionStatement(iife)]));
58
57
  }
59
58
 
59
+ function jsonToCommonJS(source: string): string {
60
+ return `module.exports = ${source};`;
61
+ }
62
+
60
63
  function wrapJson(source: string, globalPrefix: string): string {
61
64
  // Unused parameters; remember that's wrapping JSON.
62
65
  const moduleFactoryParameters = buildParameters(
63
- '_aUnused',
64
- '_bUnused',
65
- '_cUnused',
66
+ '_importDefaultUnused',
67
+ '_importAllUnused',
68
+ '_dependencyMapUnused',
66
69
  );
67
70
 
68
71
  return [
69
72
  `${globalPrefix}__d(function(${moduleFactoryParameters.join(', ')}) {`,
70
- ` module.exports = ${source};`,
73
+ ` ${jsonToCommonJS(source)}`,
71
74
  '});',
72
75
  ].join('\n');
73
76
  }
74
77
 
75
78
  function functionFromProgram(
76
- program: Ast,
79
+ program: Program,
77
80
  parameters: $ReadOnlyArray<string>,
78
- ): Ast {
81
+ ): FunctionExpression {
79
82
  return t.functionExpression(
80
- t.identifier(''),
83
+ undefined,
81
84
  parameters.map(makeIdentifier),
82
85
  t.blockStatement(program.body, program.directives),
83
86
  );
84
87
  }
85
88
 
86
- function makeIdentifier(name: string): Ast {
89
+ function makeIdentifier(name: string): Identifier {
87
90
  return t.identifier(name);
88
91
  }
89
92
 
@@ -103,13 +106,23 @@ function buildParameters(
103
106
  ];
104
107
  }
105
108
 
106
- function renameRequires(ast: Ast): string {
109
+ // Renaming requires should ideally only be done when generating for the target
110
+ // that expects the custom require name in the optimize step.
111
+ // This visitor currently renames all `require` references even if the module
112
+ // contains a custom `require` declaration. This should be fixed by only renaming
113
+ // if the `require` symbol hasn't been redeclared.
114
+ function renameRequires(ast: BabelNodeFile): string {
107
115
  let newRequireName = WRAP_NAME;
108
116
 
109
117
  traverse(ast, {
110
118
  Program(path) {
111
119
  const body = path.get('body.0.expression.arguments.0.body');
112
120
 
121
+ invariant(
122
+ !Array.isArray(body),
123
+ 'metro: Expected `body` to be a single path.',
124
+ );
125
+
113
126
  newRequireName = body.scope.generateUid(WRAP_NAME);
114
127
  body.scope.rename('require', newRequireName);
115
128
  },
@@ -122,6 +135,7 @@ module.exports = {
122
135
  WRAP_NAME,
123
136
 
124
137
  wrapJson,
138
+ jsonToCommonJS,
125
139
  wrapModule,
126
140
  wrapPolyfill,
127
141
  };