Skip to content

Commit 96fb6e9

Browse files
motiz88facebook-github-bot
authored andcommittedAug 23, 2021
Use custom resolver for Haste requests
Summary: * Allows custom Metro resolvers specified with `resolver.resolveRequest` to intercept Haste resolution requests. * Makes [`package.json`-based replacements](https://github.com/defunctzombie/package-browser-field-spec#replace-specific-files---advanced) consistently take precedence over Haste in the default resolver. These are potentially breaking changes for Metro users who have Haste enabled (though they are likely to be benign in practice). Reviewed By: GijsWeterings Differential Revision: D30425668 fbshipit-source-id: 52fc6d38a3c317b962a9f3fd4262b54c89b6f69e
1 parent c003825 commit 96fb6e9

File tree

5 files changed

+41
-22
lines changed

5 files changed

+41
-22
lines changed
 

‎docs/Configuration.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ This option works similarly to how [$NODE_PATHS](https://nodejs.org/api/modules.
137137

138138
Type: `?CustomResolver`
139139

140-
An optional function used to resolve requests. Ignored when the request can be resolved through Haste. Particularly useful for cases where aliases are used. For example:
140+
An optional function used to resolve requests. Particularly useful for cases where aliases are used. For example:
141141

142142
```javascript
143143
resolveRequest: (context, realModuleName, platform, moduleName) => {

‎packages/metro-resolver/src/__tests__/index-test.js

+33-8
Original file line numberDiff line numberDiff line change
@@ -378,25 +378,30 @@ describe('resolveRequest', () => {
378378
);
379379
});
380380

381-
it('is not called for Haste packages', () => {
381+
it('is called for Haste packages', () => {
382382
expect(Resolver.resolve(context, 'some-package', null))
383383
.toMatchInlineSnapshot(`
384384
Object {
385-
"filePath": "/haste/some-package/main.js",
386-
"type": "sourceFile",
385+
"type": "empty",
387386
}
388387
`);
389-
expect(resolveRequest).not.toBeCalled();
388+
expect(resolveRequest).toBeCalledTimes(1);
389+
expect(resolveRequest).toBeCalledWith(
390+
context,
391+
'some-package',
392+
null,
393+
'some-package',
394+
);
390395
});
391396

392-
it('is not called for Haste modules', () => {
397+
it('is called for Haste modules', () => {
393398
expect(Resolver.resolve(context, 'Foo', null)).toMatchInlineSnapshot(`
394399
Object {
395-
"filePath": "/haste/Foo.js",
396-
"type": "sourceFile",
400+
"type": "empty",
397401
}
398402
`);
399-
expect(resolveRequest).not.toBeCalled();
403+
expect(resolveRequest).toBeCalledTimes(1);
404+
expect(resolveRequest).toBeCalledWith(context, 'Foo', null, 'Foo');
400405
});
401406

402407
it('is called with the platform and redirected module path', () => {
@@ -459,6 +464,26 @@ describe('resolveRequest', () => {
459464
'does-not-exist',
460465
);
461466
});
467+
468+
it('can forward Haste requests to the standard resolver', () => {
469+
resolveRequest.mockImplementation(
470+
(ctx, realModuleName, platform, moduleName) => {
471+
return Resolver.resolve(
472+
{...ctx, resolveRequest: null},
473+
moduleName,
474+
platform,
475+
);
476+
},
477+
);
478+
expect(Resolver.resolve(context, 'Foo', null)).toMatchInlineSnapshot(`
479+
Object {
480+
"filePath": "/haste/Foo.js",
481+
"type": "sourceFile",
482+
}
483+
`);
484+
expect(resolveRequest).toBeCalledTimes(1);
485+
expect(resolveRequest).toBeCalledWith(context, 'Foo', null, 'Foo');
486+
});
462487
});
463488

464489
describe('rewriteHasteRequest', () => {

‎packages/metro-resolver/src/resolve.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,7 @@ function resolve(
7070
return resolveModulePath(context, absPath, platform);
7171
}
7272

73-
// The Haste resolution must occur before the custom resolver because we want
74-
// to allow overriding imports. It could be part of the custom resolver, but
75-
// that's not the case right now.
76-
if (context.allowHaste && !isDirectImport) {
73+
if (!resolveRequest && context.allowHaste && !isDirectImport) {
7774
const normalizedName = normalizePath(realModuleName);
7875
let nameCandidates;
7976
if (context.rewriteHasteRequest) {

‎packages/metro/src/DeltaBundler/__tests__/resolver-test.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,7 @@ let resolver;
18371837
).toBe(p('/root/node_modules/aPackage/hastePackage-local-override.js'));
18381838
});
18391839

1840-
it('ignores package.json replacements for Haste modules', async () => {
1840+
it('respects package.json replacements for Haste modules', async () => {
18411841
setMockFileSystem({
18421842
node_modules: {
18431843
aPackage: {
@@ -1859,7 +1859,7 @@ let resolver;
18591859
p('/root/node_modules/aPackage/index.js'),
18601860
'hasteModule',
18611861
),
1862-
).toBe(p('/root/hasteModule.js'));
1862+
).toBe(p('/root/node_modules/aPackage/hasteModule-local-override.js'));
18631863
});
18641864
});
18651865

@@ -2022,7 +2022,7 @@ let resolver;
20222022
);
20232023
});
20242024

2025-
it('does not override global package resolutions', async () => {
2025+
it('overrides global package resolutions', async () => {
20262026
setMockFileSystem({
20272027
'index.js': '',
20282028
aPackage: {
@@ -2035,11 +2035,11 @@ let resolver;
20352035
resolver = await createResolver({resolver: {resolveRequest}});
20362036

20372037
expect(resolver.resolve(p('/root/index.js'), 'aPackage')).toBe(
2038-
p('/root/aPackage/index.js'),
2038+
p('/root/overriden.js'),
20392039
);
20402040
});
20412041

2042-
it('does not override haste names', async () => {
2042+
it('overrides haste names', async () => {
20432043
setMockFileSystem({
20442044
'index.js': '',
20452045
'aPackage.js': '@providesModule aPackage',
@@ -2057,7 +2057,7 @@ let resolver;
20572057
});
20582058

20592059
expect(resolver.resolve(p('/root/index.js'), 'aPackage')).toBe(
2060-
p('/root/aPackage.js'),
2060+
p('/root/overriden.js'),
20612061
);
20622062
});
20632063

‎packages/metro/src/node-haste/DependencyGraph.js

-3
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,6 @@ class DependencyGraph extends EventEmitter {
301301
);
302302
let mapByPlatform = getOrCreate(mapByDirectory, to);
303303
let modulePath = mapByPlatform.get(platform);
304-
if (!modulePath) {
305-
modulePath = this._moduleMap.getModule(to, platform, true);
306-
}
307304

308305
if (!modulePath) {
309306
try {

0 commit comments

Comments
 (0)
Please sign in to comment.