metro 0.72.1 → 0.72.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +23 -21
- package/src/DeltaBundler/Serializers/baseBytecodeBundle.js +3 -2
- package/src/DeltaBundler/Serializers/baseBytecodeBundle.js.flow +2 -1
- package/src/DeltaBundler/Serializers/helpers/bytecode.js +2 -2
- package/src/DeltaBundler/Serializers/helpers/bytecode.js.flow +2 -1
- package/src/DeltaBundler.js.flow +1 -1
- package/src/HmrServer.js +9 -5
- package/src/HmrServer.js.flow +9 -4
- package/src/IncrementalBundler.js +16 -4
- package/src/IncrementalBundler.js.flow +17 -4
- package/src/ModuleGraph/node-haste/Package.js.flow +5 -5
- package/src/ModuleGraph/node-haste/node-haste.js +8 -4
- package/src/ModuleGraph/node-haste/node-haste.js.flow +21 -14
- package/src/ModuleGraph/output/util.js +2 -4
- package/src/ModuleGraph/output/util.js.flow +1 -2
- package/src/ModuleGraph/types.flow.js.flow +28 -5
- package/src/Server.js +86 -34
- package/src/Server.js.flow +106 -36
- package/src/index.flow.js +16 -8
- package/src/index.flow.js.flow +14 -8
- package/src/lib/RamBundleParser.js +1 -0
- package/src/lib/RamBundleParser.js.flow +1 -0
- package/src/lib/bundleToBytecode.js +3 -2
- package/src/lib/bundleToBytecode.js.flow +2 -2
- package/src/lib/getGraphId.js +16 -3
- package/src/lib/getGraphId.js.flow +10 -10
- package/src/lib/getPrependedScripts.js +13 -5
- package/src/lib/getPrependedScripts.js.flow +6 -1
- package/src/lib/parseCustomResolverOptions.js +26 -0
- package/src/lib/parseCustomResolverOptions.js.flow +38 -0
- package/src/lib/parseOptionsFromUrl.js +3 -0
- package/src/lib/parseOptionsFromUrl.js.flow +2 -0
- package/src/lib/splitBundleOptions.js +3 -0
- package/src/lib/splitBundleOptions.js.flow +3 -0
- package/src/lib/transformHelpers.js +27 -13
- package/src/lib/transformHelpers.js.flow +27 -7
- package/src/node-haste/DependencyGraph/ModuleResolution.js +18 -2
- package/src/node-haste/DependencyGraph/ModuleResolution.js.flow +5 -0
- package/src/node-haste/DependencyGraph.js +34 -9
- package/src/node-haste/DependencyGraph.js.flow +49 -11
- package/src/node-haste/Module.js +1 -0
- package/src/node-haste/Module.js.flow +1 -0
- package/src/shared/types.flow.js.flow +7 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+metro_bundler
|
|
8
|
+
* @format
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
const nullthrows = require("nullthrows");
|
|
14
|
+
|
|
15
|
+
const PREFIX = "resolver.";
|
|
16
|
+
|
|
17
|
+
module.exports = function parseCustomResolverOptions(urlObj) {
|
|
18
|
+
const customResolverOptions = Object.create(null);
|
|
19
|
+
const query = nullthrows(urlObj.query);
|
|
20
|
+
Object.keys(query).forEach((key) => {
|
|
21
|
+
if (key.startsWith(PREFIX)) {
|
|
22
|
+
customResolverOptions[key.substr(PREFIX.length)] = query[key];
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return customResolverOptions;
|
|
26
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+metro_bundler
|
|
8
|
+
* @format
|
|
9
|
+
* @flow strict-local
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
import type {CustomResolverOptions} from '../../../metro-resolver/src/types';
|
|
15
|
+
|
|
16
|
+
const nullthrows = require('nullthrows');
|
|
17
|
+
|
|
18
|
+
const PREFIX = 'resolver.';
|
|
19
|
+
|
|
20
|
+
module.exports = function parseCustomResolverOptions(urlObj: {
|
|
21
|
+
+query?: {[string]: string, ...},
|
|
22
|
+
...
|
|
23
|
+
}): CustomResolverOptions {
|
|
24
|
+
const customResolverOptions: {
|
|
25
|
+
__proto__: null,
|
|
26
|
+
[string]: mixed,
|
|
27
|
+
...
|
|
28
|
+
} = Object.create(null);
|
|
29
|
+
const query = nullthrows(urlObj.query);
|
|
30
|
+
|
|
31
|
+
Object.keys(query).forEach((key: string) => {
|
|
32
|
+
if (key.startsWith(PREFIX)) {
|
|
33
|
+
customResolverOptions[key.substr(PREFIX.length)] = query[key];
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return customResolverOptions;
|
|
38
|
+
};
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
const parsePlatformFilePath = require("../node-haste/lib/parsePlatformFilePath");
|
|
13
13
|
|
|
14
|
+
const parseCustomResolverOptions = require("./parseCustomResolverOptions");
|
|
15
|
+
|
|
14
16
|
const parseCustomTransformOptions = require("./parseCustomTransformOptions");
|
|
15
17
|
|
|
16
18
|
const nullthrows = require("nullthrows");
|
|
@@ -60,6 +62,7 @@ module.exports = function parseOptionsFromUrl(
|
|
|
60
62
|
bundleType,
|
|
61
63
|
runtimeBytecodeVersion:
|
|
62
64
|
bytecodeVersion === runtimeBytecodeVersion ? bytecodeVersion : null,
|
|
65
|
+
customResolverOptions: parseCustomResolverOptions(parsedURL),
|
|
63
66
|
customTransformOptions: parseCustomTransformOptions(parsedURL),
|
|
64
67
|
dev: getBoolean(query, "dev", true),
|
|
65
68
|
entryFile: pathname.replace(/^(?:\.?\/)?/, "./").replace(/\.[^/.]+$/, ""),
|
|
@@ -14,6 +14,7 @@ import type {BundleOptions} from '../shared/types.flow';
|
|
|
14
14
|
import type {TransformProfile} from 'metro-babel-transformer';
|
|
15
15
|
|
|
16
16
|
const parsePlatformFilePath = require('../node-haste/lib/parsePlatformFilePath');
|
|
17
|
+
const parseCustomResolverOptions = require('./parseCustomResolverOptions');
|
|
17
18
|
const parseCustomTransformOptions = require('./parseCustomTransformOptions');
|
|
18
19
|
const nullthrows = require('nullthrows');
|
|
19
20
|
const path = require('path');
|
|
@@ -68,6 +69,7 @@ module.exports = function parseOptionsFromUrl(
|
|
|
68
69
|
bundleType,
|
|
69
70
|
runtimeBytecodeVersion:
|
|
70
71
|
bytecodeVersion === runtimeBytecodeVersion ? bytecodeVersion : null,
|
|
72
|
+
customResolverOptions: parseCustomResolverOptions(parsedURL),
|
|
71
73
|
customTransformOptions: parseCustomTransformOptions(parsedURL),
|
|
72
74
|
dev: getBoolean(query, 'dev', true),
|
|
73
75
|
entryFile: pathname.replace(/^(?:\.?\/)?/, './').replace(/\.[^/.]+$/, ''),
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
function splitBundleOptions(options) {
|
|
16
16
|
return {
|
|
17
17
|
entryFile: options.entryFile,
|
|
18
|
+
resolverOptions: {
|
|
19
|
+
customResolverOptions: options.customResolverOptions,
|
|
20
|
+
},
|
|
18
21
|
transformOptions: {
|
|
19
22
|
customTransformOptions: options.customTransformOptions,
|
|
20
23
|
dev: options.dev,
|
|
@@ -18,6 +18,9 @@ import type {BundleOptions, SplitBundleOptions} from '../shared/types.flow';
|
|
|
18
18
|
function splitBundleOptions(options: BundleOptions): SplitBundleOptions {
|
|
19
19
|
return {
|
|
20
20
|
entryFile: options.entryFile,
|
|
21
|
+
resolverOptions: {
|
|
22
|
+
customResolverOptions: options.customResolverOptions,
|
|
23
|
+
},
|
|
21
24
|
transformOptions: {
|
|
22
25
|
customTransformOptions: options.customTransformOptions,
|
|
23
26
|
dev: options.dev,
|
|
@@ -20,7 +20,8 @@ async function calcTransformerOptions(
|
|
|
20
20
|
bundler,
|
|
21
21
|
deltaBundler,
|
|
22
22
|
config,
|
|
23
|
-
options
|
|
23
|
+
options,
|
|
24
|
+
resolverOptions
|
|
24
25
|
) {
|
|
25
26
|
const baseOptions = {
|
|
26
27
|
customTransformOptions: options.customTransformOptions,
|
|
@@ -42,11 +43,19 @@ async function calcTransformerOptions(
|
|
|
42
43
|
|
|
43
44
|
const getDependencies = async (path) => {
|
|
44
45
|
const dependencies = await deltaBundler.getDependencies([path], {
|
|
45
|
-
resolve: await getResolveDependencyFn(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
resolve: await getResolveDependencyFn(
|
|
47
|
+
bundler,
|
|
48
|
+
options.platform,
|
|
49
|
+
resolverOptions
|
|
50
|
+
),
|
|
51
|
+
transform: await getTransformFn(
|
|
52
|
+
[path],
|
|
53
|
+
bundler,
|
|
54
|
+
deltaBundler,
|
|
55
|
+
config,
|
|
56
|
+
{ ...options, minify: false },
|
|
57
|
+
resolverOptions
|
|
58
|
+
),
|
|
50
59
|
transformOptions: options,
|
|
51
60
|
onProgress: null,
|
|
52
61
|
experimentalImportBundleSupport:
|
|
@@ -92,14 +101,16 @@ async function getTransformFn(
|
|
|
92
101
|
bundler,
|
|
93
102
|
deltaBundler,
|
|
94
103
|
config,
|
|
95
|
-
options
|
|
104
|
+
options,
|
|
105
|
+
resolverOptions
|
|
96
106
|
) {
|
|
97
107
|
const { inlineRequires, ...transformOptions } = await calcTransformerOptions(
|
|
98
108
|
entryFiles,
|
|
99
109
|
bundler,
|
|
100
110
|
deltaBundler,
|
|
101
111
|
config,
|
|
102
|
-
options
|
|
112
|
+
options,
|
|
113
|
+
resolverOptions
|
|
103
114
|
);
|
|
104
115
|
return async (modulePath, requireContext) => {
|
|
105
116
|
let templateBuffer;
|
|
@@ -153,12 +164,15 @@ function getType(type, filePath, assetExts) {
|
|
|
153
164
|
return "module";
|
|
154
165
|
}
|
|
155
166
|
|
|
156
|
-
async function getResolveDependencyFn(bundler, platform) {
|
|
167
|
+
async function getResolveDependencyFn(bundler, platform, resolverOptions) {
|
|
157
168
|
const dependencyGraph = await await bundler.getDependencyGraph();
|
|
158
|
-
return (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
return (from, to) =>
|
|
170
|
+
dependencyGraph.resolveDependency(
|
|
171
|
+
from,
|
|
172
|
+
to,
|
|
173
|
+
platform !== null && platform !== void 0 ? platform : null,
|
|
174
|
+
resolverOptions
|
|
175
|
+
);
|
|
162
176
|
}
|
|
163
177
|
|
|
164
178
|
module.exports = {
|
|
@@ -21,6 +21,7 @@ import type {RequireContext} from './contextModule';
|
|
|
21
21
|
import {getContextModuleTemplate} from './contextModuleTemplates';
|
|
22
22
|
|
|
23
23
|
const path = require('path');
|
|
24
|
+
import type {ResolverInputOptions} from '../shared/types.flow';
|
|
24
25
|
|
|
25
26
|
type InlineRequiresRaw = {+blockList: {[string]: true, ...}, ...} | boolean;
|
|
26
27
|
|
|
@@ -37,6 +38,7 @@ async function calcTransformerOptions(
|
|
|
37
38
|
deltaBundler: DeltaBundler<>,
|
|
38
39
|
config: ConfigT,
|
|
39
40
|
options: TransformInputOptions,
|
|
41
|
+
resolverOptions: ResolverInputOptions,
|
|
40
42
|
): Promise<TransformOptionsWithRawInlines> {
|
|
41
43
|
const baseOptions = {
|
|
42
44
|
customTransformOptions: options.customTransformOptions,
|
|
@@ -62,11 +64,22 @@ async function calcTransformerOptions(
|
|
|
62
64
|
|
|
63
65
|
const getDependencies = async (path: string) => {
|
|
64
66
|
const dependencies = await deltaBundler.getDependencies([path], {
|
|
65
|
-
resolve: await getResolveDependencyFn(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
resolve: await getResolveDependencyFn(
|
|
68
|
+
bundler,
|
|
69
|
+
options.platform,
|
|
70
|
+
resolverOptions,
|
|
71
|
+
),
|
|
72
|
+
transform: await getTransformFn(
|
|
73
|
+
[path],
|
|
74
|
+
bundler,
|
|
75
|
+
deltaBundler,
|
|
76
|
+
config,
|
|
77
|
+
{
|
|
78
|
+
...options,
|
|
79
|
+
minify: false,
|
|
80
|
+
},
|
|
81
|
+
resolverOptions,
|
|
82
|
+
),
|
|
70
83
|
transformOptions: options,
|
|
71
84
|
onProgress: null,
|
|
72
85
|
experimentalImportBundleSupport:
|
|
@@ -114,6 +127,7 @@ async function getTransformFn(
|
|
|
114
127
|
deltaBundler: DeltaBundler<>,
|
|
115
128
|
config: ConfigT,
|
|
116
129
|
options: TransformInputOptions,
|
|
130
|
+
resolverOptions: ResolverInputOptions,
|
|
117
131
|
): Promise<TransformFn<>> {
|
|
118
132
|
const {inlineRequires, ...transformOptions} = await calcTransformerOptions(
|
|
119
133
|
entryFiles,
|
|
@@ -121,6 +135,7 @@ async function getTransformFn(
|
|
|
121
135
|
deltaBundler,
|
|
122
136
|
config,
|
|
123
137
|
options,
|
|
138
|
+
resolverOptions,
|
|
124
139
|
);
|
|
125
140
|
|
|
126
141
|
return async (modulePath: string, requireContext: ?RequireContext) => {
|
|
@@ -186,12 +201,17 @@ function getType(
|
|
|
186
201
|
async function getResolveDependencyFn(
|
|
187
202
|
bundler: Bundler,
|
|
188
203
|
platform: ?string,
|
|
204
|
+
resolverOptions: ResolverInputOptions,
|
|
189
205
|
): Promise<(from: string, to: string) => string> {
|
|
190
206
|
const dependencyGraph = await await bundler.getDependencyGraph();
|
|
191
207
|
|
|
192
208
|
return (from: string, to: string) =>
|
|
193
|
-
|
|
194
|
-
|
|
209
|
+
dependencyGraph.resolveDependency(
|
|
210
|
+
from,
|
|
211
|
+
to,
|
|
212
|
+
platform ?? null,
|
|
213
|
+
resolverOptions,
|
|
214
|
+
);
|
|
195
215
|
}
|
|
196
216
|
|
|
197
217
|
module.exports = {
|
|
@@ -24,6 +24,7 @@ const util = require("util");
|
|
|
24
24
|
class ModuleResolver {
|
|
25
25
|
// A module representing the project root, used as the origin when resolving `emptyModulePath`.
|
|
26
26
|
// An empty module, the result of resolving `emptyModulePath` from the project root.
|
|
27
|
+
// $FlowFixMe[missing-local-annot]
|
|
27
28
|
constructor(options) {
|
|
28
29
|
this._options = options;
|
|
29
30
|
const { projectRoot, moduleCache } = this._options;
|
|
@@ -50,7 +51,9 @@ class ModuleResolver {
|
|
|
50
51
|
this._projectRootFakeModule,
|
|
51
52
|
this._options.emptyModulePath,
|
|
52
53
|
false,
|
|
53
|
-
null
|
|
54
|
+
null,
|
|
55
|
+
/* resolverOptions */
|
|
56
|
+
{}
|
|
54
57
|
);
|
|
55
58
|
this._cachedEmptyModule = emptyModule;
|
|
56
59
|
}
|
|
@@ -110,11 +113,24 @@ class ModuleResolver {
|
|
|
110
113
|
return modulePath;
|
|
111
114
|
}
|
|
112
115
|
|
|
113
|
-
resolveDependency(
|
|
116
|
+
resolveDependency(
|
|
117
|
+
fromModule,
|
|
118
|
+
moduleName,
|
|
119
|
+
allowHaste,
|
|
120
|
+
platform,
|
|
121
|
+
resolverOptions
|
|
122
|
+
) {
|
|
114
123
|
try {
|
|
124
|
+
var _resolverOptions$cust;
|
|
125
|
+
|
|
115
126
|
const result = Resolver.resolve(
|
|
116
127
|
{
|
|
117
128
|
...this._options,
|
|
129
|
+
customResolverOptions:
|
|
130
|
+
(_resolverOptions$cust = resolverOptions.customResolverOptions) !==
|
|
131
|
+
null && _resolverOptions$cust !== void 0
|
|
132
|
+
? _resolverOptions$cust
|
|
133
|
+
: {},
|
|
118
134
|
originModulePath: fromModule.path,
|
|
119
135
|
redirectModulePath: (modulePath) =>
|
|
120
136
|
this._redirectRequire(fromModule, modulePath),
|
|
@@ -26,6 +26,7 @@ const invariant = require('invariant');
|
|
|
26
26
|
const Resolver = require('metro-resolver');
|
|
27
27
|
const path = require('path');
|
|
28
28
|
const util = require('util');
|
|
29
|
+
import type {ResolverInputOptions} from '../../shared/types.flow';
|
|
29
30
|
|
|
30
31
|
export type DirExistsFn = (filePath: string) => boolean;
|
|
31
32
|
|
|
@@ -78,6 +79,7 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
|
|
|
78
79
|
// An empty module, the result of resolving `emptyModulePath` from the project root.
|
|
79
80
|
_cachedEmptyModule: ?TModule;
|
|
80
81
|
|
|
82
|
+
// $FlowFixMe[missing-local-annot]
|
|
81
83
|
constructor(options: Options<TModule, TPackage>) {
|
|
82
84
|
this._options = options;
|
|
83
85
|
const {projectRoot, moduleCache} = this._options;
|
|
@@ -102,6 +104,7 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
|
|
|
102
104
|
this._options.emptyModulePath,
|
|
103
105
|
false,
|
|
104
106
|
null,
|
|
107
|
+
/* resolverOptions */ {},
|
|
105
108
|
);
|
|
106
109
|
this._cachedEmptyModule = emptyModule;
|
|
107
110
|
}
|
|
@@ -166,11 +169,13 @@ class ModuleResolver<TModule: Moduleish, TPackage: Packageish> {
|
|
|
166
169
|
moduleName: string,
|
|
167
170
|
allowHaste: boolean,
|
|
168
171
|
platform: string | null,
|
|
172
|
+
resolverOptions: ResolverInputOptions,
|
|
169
173
|
): TModule {
|
|
170
174
|
try {
|
|
171
175
|
const result = Resolver.resolve(
|
|
172
176
|
{
|
|
173
177
|
...this._options,
|
|
178
|
+
customResolverOptions: resolverOptions.customResolverOptions ?? {},
|
|
174
179
|
originModulePath: fromModule.path,
|
|
175
180
|
redirectModulePath: (modulePath: string) =>
|
|
176
181
|
this._redirectRequire(fromModule, modulePath),
|
|
@@ -11,6 +11,8 @@ var _metroFileMap = require("metro-file-map");
|
|
|
11
11
|
*
|
|
12
12
|
* @format
|
|
13
13
|
*/
|
|
14
|
+
const canonicalize = require("metro-core/src/canonicalize");
|
|
15
|
+
|
|
14
16
|
const createHasteMap = require("./DependencyGraph/createHasteMap");
|
|
15
17
|
|
|
16
18
|
const { ModuleResolver } = require("./DependencyGraph/ModuleResolution");
|
|
@@ -34,8 +36,9 @@ const nullthrows = require("nullthrows");
|
|
|
34
36
|
const path = require("path");
|
|
35
37
|
|
|
36
38
|
const { DuplicateHasteCandidatesError } = _metroFileMap.ModuleMap;
|
|
39
|
+
const NULL_PLATFORM = Symbol();
|
|
37
40
|
|
|
38
|
-
function
|
|
41
|
+
function getOrCreateMap(map, field) {
|
|
39
42
|
let subMap = map.get(field);
|
|
40
43
|
|
|
41
44
|
if (!subMap) {
|
|
@@ -218,22 +221,43 @@ class DependencyGraph extends EventEmitter {
|
|
|
218
221
|
from,
|
|
219
222
|
to,
|
|
220
223
|
platform,
|
|
224
|
+
resolverOptions, // TODO: Fold assumeFlatNodeModules into resolverOptions and add to graphId
|
|
221
225
|
{ assumeFlatNodeModules } = {
|
|
222
226
|
assumeFlatNodeModules: false,
|
|
223
227
|
}
|
|
224
228
|
) {
|
|
229
|
+
var _JSON$stringify, _resolverOptions$cust;
|
|
230
|
+
|
|
225
231
|
const isSensitiveToOriginFolder = // Resolution is always relative to the origin folder unless we assume a flat node_modules
|
|
226
232
|
!assumeFlatNodeModules || // Path requests are resolved relative to the origin folder
|
|
227
233
|
to.includes("/") ||
|
|
228
234
|
to === "." ||
|
|
229
235
|
to === ".." || // Preserve standard assumptions under node_modules
|
|
230
|
-
from.includes(path.sep + "node_modules" + path.sep);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
236
|
+
from.includes(path.sep + "node_modules" + path.sep); // Compound key for the resolver cache
|
|
237
|
+
|
|
238
|
+
const resolverOptionsKey =
|
|
239
|
+
(_JSON$stringify = JSON.stringify(
|
|
240
|
+
(_resolverOptions$cust = resolverOptions.customResolverOptions) !==
|
|
241
|
+
null && _resolverOptions$cust !== void 0
|
|
242
|
+
? _resolverOptions$cust
|
|
243
|
+
: {},
|
|
244
|
+
canonicalize
|
|
245
|
+
)) !== null && _JSON$stringify !== void 0
|
|
246
|
+
? _JSON$stringify
|
|
247
|
+
: "";
|
|
248
|
+
const originKey = isSensitiveToOriginFolder ? path.dirname(from) : "";
|
|
249
|
+
const targetKey = to;
|
|
250
|
+
const platformKey =
|
|
251
|
+
platform !== null && platform !== void 0 ? platform : NULL_PLATFORM; // Traverse the resolver cache, which is a tree of maps
|
|
252
|
+
|
|
253
|
+
const mapByResolverOptions = this._resolutionCache;
|
|
254
|
+
const mapByOrigin = getOrCreateMap(
|
|
255
|
+
mapByResolverOptions,
|
|
256
|
+
resolverOptionsKey
|
|
234
257
|
);
|
|
235
|
-
const
|
|
236
|
-
|
|
258
|
+
const mapByTarget = getOrCreateMap(mapByOrigin, originKey);
|
|
259
|
+
const mapByPlatform = getOrCreateMap(mapByTarget, targetKey);
|
|
260
|
+
let modulePath = mapByPlatform.get(platformKey);
|
|
237
261
|
|
|
238
262
|
if (!modulePath) {
|
|
239
263
|
try {
|
|
@@ -241,7 +265,8 @@ class DependencyGraph extends EventEmitter {
|
|
|
241
265
|
this._moduleCache.getModule(from),
|
|
242
266
|
to,
|
|
243
267
|
true,
|
|
244
|
-
platform
|
|
268
|
+
platform,
|
|
269
|
+
resolverOptions
|
|
245
270
|
).path;
|
|
246
271
|
} catch (error) {
|
|
247
272
|
if (error instanceof DuplicateHasteCandidatesError) {
|
|
@@ -260,7 +285,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
260
285
|
}
|
|
261
286
|
}
|
|
262
287
|
|
|
263
|
-
mapByPlatform.set(
|
|
288
|
+
mapByPlatform.set(platformKey, modulePath);
|
|
264
289
|
return modulePath;
|
|
265
290
|
}
|
|
266
291
|
|
|
@@ -15,6 +15,7 @@ import type Module from './Module';
|
|
|
15
15
|
|
|
16
16
|
import {ModuleMap as MetroFileMapModuleMap} from 'metro-file-map';
|
|
17
17
|
|
|
18
|
+
const canonicalize = require('metro-core/src/canonicalize');
|
|
18
19
|
const createHasteMap = require('./DependencyGraph/createHasteMap');
|
|
19
20
|
const {ModuleResolver} = require('./DependencyGraph/ModuleResolution');
|
|
20
21
|
const ModuleCache = require('./ModuleCache');
|
|
@@ -28,13 +29,16 @@ const {
|
|
|
28
29
|
const {InvalidPackageError} = require('metro-resolver');
|
|
29
30
|
const nullthrows = require('nullthrows');
|
|
30
31
|
const path = require('path');
|
|
32
|
+
import type {ResolverInputOptions} from '../shared/types.flow';
|
|
31
33
|
|
|
32
34
|
const {DuplicateHasteCandidatesError} = MetroFileMapModuleMap;
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const NULL_PLATFORM = Symbol();
|
|
37
|
+
|
|
38
|
+
function getOrCreateMap<T>(
|
|
39
|
+
map: Map<string | symbol, Map<string | symbol, T>>,
|
|
36
40
|
field: string,
|
|
37
|
-
): Map<string, T> {
|
|
41
|
+
): Map<string | symbol, T> {
|
|
38
42
|
let subMap = map.get(field);
|
|
39
43
|
if (!subMap) {
|
|
40
44
|
subMap = new Map();
|
|
@@ -51,7 +55,23 @@ class DependencyGraph extends EventEmitter {
|
|
|
51
55
|
_moduleCache: ModuleCache;
|
|
52
56
|
_moduleMap: MetroFileMapModuleMap;
|
|
53
57
|
_moduleResolver: ModuleResolver<Module, Package>;
|
|
54
|
-
_resolutionCache: Map<
|
|
58
|
+
_resolutionCache: Map<
|
|
59
|
+
// Custom resolver options
|
|
60
|
+
string | symbol,
|
|
61
|
+
Map<
|
|
62
|
+
// Origin folder
|
|
63
|
+
string | symbol,
|
|
64
|
+
Map<
|
|
65
|
+
// Dependency name
|
|
66
|
+
string | symbol,
|
|
67
|
+
Map<
|
|
68
|
+
// Platform
|
|
69
|
+
string | symbol,
|
|
70
|
+
string,
|
|
71
|
+
>,
|
|
72
|
+
>,
|
|
73
|
+
>,
|
|
74
|
+
>;
|
|
55
75
|
_readyPromise: Promise<void>;
|
|
56
76
|
|
|
57
77
|
constructor(
|
|
@@ -241,7 +261,10 @@ class DependencyGraph extends EventEmitter {
|
|
|
241
261
|
resolveDependency(
|
|
242
262
|
from: string,
|
|
243
263
|
to: string,
|
|
244
|
-
platform: string,
|
|
264
|
+
platform: string | null,
|
|
265
|
+
resolverOptions: ResolverInputOptions,
|
|
266
|
+
|
|
267
|
+
// TODO: Fold assumeFlatNodeModules into resolverOptions and add to graphId
|
|
245
268
|
{assumeFlatNodeModules}: {assumeFlatNodeModules: boolean} = {
|
|
246
269
|
assumeFlatNodeModules: false,
|
|
247
270
|
},
|
|
@@ -255,12 +278,26 @@ class DependencyGraph extends EventEmitter {
|
|
|
255
278
|
to === '..' ||
|
|
256
279
|
// Preserve standard assumptions under node_modules
|
|
257
280
|
from.includes(path.sep + 'node_modules' + path.sep);
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
281
|
+
|
|
282
|
+
// Compound key for the resolver cache
|
|
283
|
+
const resolverOptionsKey =
|
|
284
|
+
JSON.stringify(
|
|
285
|
+
resolverOptions.customResolverOptions ?? {},
|
|
286
|
+
canonicalize,
|
|
287
|
+
) ?? '';
|
|
288
|
+
const originKey = isSensitiveToOriginFolder ? path.dirname(from) : '';
|
|
289
|
+
const targetKey = to;
|
|
290
|
+
const platformKey = platform ?? NULL_PLATFORM;
|
|
291
|
+
|
|
292
|
+
// Traverse the resolver cache, which is a tree of maps
|
|
293
|
+
const mapByResolverOptions = this._resolutionCache;
|
|
294
|
+
const mapByOrigin = getOrCreateMap(
|
|
295
|
+
mapByResolverOptions,
|
|
296
|
+
resolverOptionsKey,
|
|
261
297
|
);
|
|
262
|
-
const
|
|
263
|
-
|
|
298
|
+
const mapByTarget = getOrCreateMap(mapByOrigin, originKey);
|
|
299
|
+
const mapByPlatform = getOrCreateMap(mapByTarget, targetKey);
|
|
300
|
+
let modulePath = mapByPlatform.get(platformKey);
|
|
264
301
|
|
|
265
302
|
if (!modulePath) {
|
|
266
303
|
try {
|
|
@@ -269,6 +306,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
269
306
|
to,
|
|
270
307
|
true,
|
|
271
308
|
platform,
|
|
309
|
+
resolverOptions,
|
|
272
310
|
).path;
|
|
273
311
|
} catch (error) {
|
|
274
312
|
if (error instanceof DuplicateHasteCandidatesError) {
|
|
@@ -285,7 +323,7 @@ class DependencyGraph extends EventEmitter {
|
|
|
285
323
|
}
|
|
286
324
|
}
|
|
287
325
|
|
|
288
|
-
mapByPlatform.set(
|
|
326
|
+
mapByPlatform.set(platformKey, modulePath);
|
|
289
327
|
return modulePath;
|
|
290
328
|
}
|
|
291
329
|
|
package/src/node-haste/Module.js
CHANGED
|
@@ -21,6 +21,7 @@ class Module {
|
|
|
21
21
|
_moduleCache: ModuleCache;
|
|
22
22
|
_sourceCode: ?string;
|
|
23
23
|
|
|
24
|
+
// $FlowFixMe[missing-local-annot]
|
|
24
25
|
constructor(file: string, moduleCache: ModuleCache) {
|
|
25
26
|
if (!isAbsolutePath(file)) {
|
|
26
27
|
throw new Error('Expected file to be absolute path but got ' + file);
|
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
CustomTransformOptions,
|
|
24
24
|
MinifierOptions,
|
|
25
25
|
} from 'metro-transform-worker';
|
|
26
|
+
import type {CustomResolverOptions} from 'metro-resolver';
|
|
26
27
|
|
|
27
28
|
type BundleType =
|
|
28
29
|
| 'bundle'
|
|
@@ -41,6 +42,7 @@ type MetroSourceMapOrMappings =
|
|
|
41
42
|
|
|
42
43
|
export type BundleOptions = {
|
|
43
44
|
bundleType: BundleType,
|
|
45
|
+
+customResolverOptions: CustomResolverOptions,
|
|
44
46
|
customTransformOptions: CustomTransformOptions,
|
|
45
47
|
dev: boolean,
|
|
46
48
|
entryFile: string,
|
|
@@ -61,6 +63,10 @@ export type BundleOptions = {
|
|
|
61
63
|
...
|
|
62
64
|
};
|
|
63
65
|
|
|
66
|
+
export type ResolverInputOptions = $ReadOnly<{
|
|
67
|
+
customResolverOptions?: CustomResolverOptions,
|
|
68
|
+
}>;
|
|
69
|
+
|
|
64
70
|
export type SerializerOptions = {
|
|
65
71
|
+sourceMapUrl: ?string,
|
|
66
72
|
+sourceUrl: ?string,
|
|
@@ -77,6 +83,7 @@ export type GraphOptions = {
|
|
|
77
83
|
// Stricter representation of BundleOptions.
|
|
78
84
|
export type SplitBundleOptions = {
|
|
79
85
|
+entryFile: string,
|
|
86
|
+
+resolverOptions: ResolverInputOptions,
|
|
80
87
|
+transformOptions: TransformInputOptions,
|
|
81
88
|
+serializerOptions: SerializerOptions,
|
|
82
89
|
+graphOptions: GraphOptions,
|