Skip to content

Commit 9caa7c0

Browse files
authored
feat(jest-resolver): support file:// URLs (#15154)
1 parent 6e7c568 commit 9caa7c0

File tree

6 files changed

+29
-4
lines changed

6 files changed

+29
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- `[jest-matcher-utils]` Add `SERIALIZABLE_PROPERTIES` to allow custom serialization of objects ([#14893](https://github.com/jestjs/jest/pull/14893))
2727
- `[jest-mock]` Add support for the Explicit Resource Management proposal to use the `using` keyword with `jest.spyOn(object, methodName)` ([#14895](https://github.com/jestjs/jest/pull/14895))
2828
- `[jest-reporters]` Add support for [DEC mode 2026](https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036) ([#15008](https://github.com/jestjs/jest/pull/15008))
29+
- `[jest-resolver]` Support `file://` URLs as paths ([#15154](https://github.com/jestjs/jest/pull/15154))
2930
- `[jest-runtime]` Exposing new modern timers function `jest.advanceTimersToFrame()` from `@jest/fake-timers` ([#14598](https://github.com/jestjs/jest/pull/14598))
3031
- `[jest-runtime]` Support `import.meta.filename` and `import.meta.dirname` (available from [Node 20.11](https://nodejs.org/en/blog/release/v20.11.0)) ([#14854](https://github.com/jestjs/jest/pull/14854))
3132
- `[jest-runtime]` Support `import.meta.resolve` ([#14930](https://github.com/jestjs/jest/pull/14930))

e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ exports[`moduleNameMapper wrong array configuration 1`] = `
4141
12 | module.exports = () => 'test';
4242
13 |
4343
44-
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1172:17)
44+
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1182:17)
4545
at Object.require (index.js:10:1)
4646
at Object.require (__tests__/index.js:10:20)"
4747
`;
@@ -71,7 +71,7 @@ exports[`moduleNameMapper wrong configuration 1`] = `
7171
12 | module.exports = () => 'test';
7272
13 |
7373
74-
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1172:17)
74+
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:1182:17)
7575
at Object.require (index.js:10:1)
7676
at Object.require (__tests__/index.js:10:20)"
7777
`;

e2e/__tests__/__snapshots__/requireMissingExt.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ exports[`shows a proper error from deep requires 1`] = `
2626
12 | test('dummy', () => {
2727
13 | expect(1).toBe(1);
2828
29-
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:927:11)
29+
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:937:11)
3030
at Object.<anonymous> (node_modules/discord.js/src/index.js:21:12)
3131
at Object.require (__tests__/test.js:10:1)"
3232
`;

e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ exports[`show error message with matching files 1`] = `
3737
| ^
3838
9 |
3939
40-
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:927:11)
40+
at Resolver._throwModNotFoundError (../../packages/jest-resolve/build/index.js:937:11)
4141
at Object.require (index.js:8:18)
4242
at Object.require (__tests__/test.js:8:11)"
4343
`;

packages/jest-resolve/src/__tests__/resolve.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import * as path from 'path';
10+
import {fileURLToPath, pathToFileURL} from 'url';
1011
import * as fs from 'graceful-fs';
1112
import {sync as resolveSync} from 'resolve';
1213
import {type IModuleMap, ModuleMap} from 'jest-haste-map';
@@ -152,6 +153,15 @@ describe('findNodeModule', () => {
152153
);
153154
});
154155

156+
it('supports file URLs', () => {
157+
const path = pathToFileURL(__filename).href;
158+
const newPath = Resolver.findNodeModule(path, {
159+
basedir: '/',
160+
});
161+
162+
expect(newPath).toBe(__filename);
163+
});
164+
155165
describe('conditions', () => {
156166
const conditionsRoot = path.resolve(__dirname, '../__mocks__/conditions');
157167

@@ -456,6 +466,15 @@ describe('findNodeModuleAsync', () => {
456466
}),
457467
);
458468
});
469+
470+
it('supports file URLs', async () => {
471+
const path = pathToFileURL(__filename).href;
472+
const newPath = await Resolver.findNodeModuleAsync(path, {
473+
basedir: '/',
474+
});
475+
476+
expect(newPath).toBe(__filename);
477+
});
459478
});
460479

461480
describe('resolveModule', () => {

packages/jest-resolve/src/defaultResolver.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
import {dirname, isAbsolute, resolve as pathResolve} from 'path';
9+
import {fileURLToPath} from 'url';
910
import pnpResolver from 'jest-pnp-resolver';
1011
import {
1112
type SyncOpts as UpstreamResolveOptions,
@@ -132,6 +133,10 @@ function getPathInModule(
132133
path: string,
133134
options: UpstreamResolveOptionsWithConditions,
134135
): string {
136+
if (path.startsWith('file://')) {
137+
path = fileURLToPath(path);
138+
}
139+
135140
if (shouldIgnoreRequestForExports(path)) {
136141
return path;
137142
}

0 commit comments

Comments
 (0)