Skip to content

Commit ea5e47e

Browse files
authored
refactor(resolve): use resolve.exports for imports (#13777)
1 parent 8ef8c20 commit ea5e47e

File tree

5 files changed

+44
-85
lines changed

5 files changed

+44
-85
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
- `[jest-config, jest-worker]` Use `os.availableParallelism` if available to calculate number of workers to spawn ([#13738](https://github.com/facebook/jest/pull/13738))
77
- `[@jest/globals, jest-mock]` Add `jest.replaceProperty()` that replaces property value ([#13496](https://github.com/facebook/jest/pull/13496))
88
- `[jest-haste-map]` ignore Sapling vcs directories (`.sl/`) ([#13674](https://github.com/facebook/jest/pull/13674))
9-
- `[jest-resolve]` Support subpath imports ([#13705](https://github.com/facebook/jest/pull/13705), [#13723](https://github.com/facebook/jest/pull/13723))
9+
- `[jest-resolve]` Support subpath imports ([#13705](https://github.com/facebook/jest/pull/13705), [#13723](https://github.com/facebook/jest/pull/13723)), [#13777](https://github.com/facebook/jest/pull/13777))
1010
- `[jest-runtime]` Add `jest.isolateModulesAsync` for scoped module initialization of asynchronous functions ([#13680](https://github.com/facebook/jest/pull/13680))
1111
- `[jest-runtime]` Add `jest.isEnvironmentTornDown` function ([#13698](https://github.com/facebook/jest/pull/13698))
1212
- `[jest-test-result]` Added `skipped` and `focused` status to `FormattedTestResult` ([#13700](https://github.com/facebook/jest/pull/13700))

packages/jest-resolve/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
"jest-util": "workspace:^",
2525
"jest-validate": "workspace:^",
2626
"resolve": "^1.20.0",
27-
"resolve.exports": "^1.1.1",
28-
"resolve.imports": "^2.0.3",
27+
"resolve.exports": "^2.0.0",
2928
"slash": "^3.0.0"
3029
},
3130
"devDependencies": {

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

+1-8
Original file line numberDiff line numberDiff line change
@@ -397,14 +397,7 @@ describe('findNodeModule', () => {
397397
basedir: path.resolve(importsRoot, './foo-import/index.js'),
398398
conditions: [],
399399
});
400-
}).toThrow(
401-
expect.objectContaining({
402-
code: 'ERR_PACKAGE_IMPORT_NOT_DEFINED',
403-
message: expect.stringMatching(
404-
/^Package import specifier "#something-else" is not defined in package/,
405-
),
406-
}),
407-
);
400+
}).toThrow('Missing "#something-else" specifier in "foo-import" package');
408401
});
409402
});
410403
});

packages/jest-resolve/src/defaultResolver.ts

+36-52
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88
import {dirname, isAbsolute, resolve as pathResolve} from 'path';
99
import pnpResolver from 'jest-pnp-resolver';
1010
import {SyncOpts as UpstreamResolveOptions, sync as resolveSync} from 'resolve';
11-
import {
12-
Options as ResolveExportsOptions,
13-
resolve as resolveExports,
14-
} from 'resolve.exports';
15-
import {resolve as resolveImports} from 'resolve.imports';
11+
import * as resolve from 'resolve.exports';
1612
import {
1713
findClosestPackageJson,
1814
isDirectory,
@@ -148,28 +144,26 @@ function getPathInModule(
148144

149145
const pkg = readPackageCached(closestPackageJson);
150146

151-
const resolved = resolveImports(
152-
{
153-
base: options.basedir,
154-
content: pkg,
155-
path: dirname(closestPackageJson),
156-
},
157-
path,
158-
createImportsResolveOptions(options.conditions),
147+
const resolved = resolve.imports(
148+
pkg,
149+
path as resolve.Imports.Entry,
150+
createResolveOptions(options.conditions),
159151
);
160152

161-
if (!resolved) {
153+
if (resolved) {
154+
const target = resolved[0];
155+
return target.startsWith('.')
156+
? // internal relative filepath
157+
pathResolve(dirname(closestPackageJson), target)
158+
: // this is an external module, re-resolve it
159+
defaultResolver(target, options);
160+
}
161+
162+
if (pkg.imports) {
162163
throw new Error(
163164
'`imports` exists, but no results - this is a bug in Jest. Please report an issue',
164165
);
165166
}
166-
167-
if (resolved.startsWith('.')) {
168-
return pathResolve(dirname(closestPackageJson), resolved);
169-
}
170-
171-
// this is an external module, re-resolve it
172-
return defaultResolver(resolved, options);
173167
}
174168

175169
const segments = path.split('/');
@@ -186,22 +180,22 @@ function getPathInModule(
186180
if (closestPackageJson) {
187181
const pkg = readPackageCached(closestPackageJson);
188182

189-
if (pkg.name === moduleName && pkg.exports) {
190-
const subpath = segments.join('/') || '.';
191-
192-
const resolved = resolveExports(
183+
if (pkg.name === moduleName) {
184+
const resolved = resolve.exports(
193185
pkg,
194-
subpath,
186+
(segments.join('/') || '.') as resolve.Exports.Entry,
195187
createResolveOptions(options.conditions),
196188
);
197189

198-
if (!resolved) {
190+
if (resolved) {
191+
return pathResolve(dirname(closestPackageJson), resolved[0]);
192+
}
193+
194+
if (pkg.exports) {
199195
throw new Error(
200196
'`exports` exists, but no results - this is a bug in Jest. Please report an issue',
201197
);
202198
}
203-
204-
return pathResolve(dirname(closestPackageJson), resolved);
205199
}
206200
}
207201

@@ -216,22 +210,20 @@ function getPathInModule(
216210
if (packageJsonPath && isFile(packageJsonPath)) {
217211
const pkg = readPackageCached(packageJsonPath);
218212

219-
if (pkg.exports) {
220-
const subpath = segments.join('/') || '.';
221-
222-
const resolved = resolveExports(
223-
pkg,
224-
subpath,
225-
createResolveOptions(options.conditions),
226-
);
213+
const resolved = resolve.exports(
214+
pkg,
215+
(segments.join('/') || '.') as resolve.Exports.Entry,
216+
createResolveOptions(options.conditions),
217+
);
227218

228-
if (!resolved) {
229-
throw new Error(
230-
'`exports` exists, but no results - this is a bug in Jest. Please report an issue',
231-
);
232-
}
219+
if (resolved) {
220+
return pathResolve(dirname(packageJsonPath), resolved[0]);
221+
}
233222

234-
return pathResolve(dirname(packageJsonPath), resolved);
223+
if (pkg.exports) {
224+
throw new Error(
225+
'`exports` exists, but no results - this is a bug in Jest. Please report an issue',
226+
);
235227
}
236228
}
237229
}
@@ -241,21 +233,13 @@ function getPathInModule(
241233

242234
function createResolveOptions(
243235
conditions: Array<string> | undefined,
244-
): ResolveExportsOptions {
236+
): resolve.Options {
245237
return conditions
246238
? {conditions, unsafe: true}
247239
: // no conditions were passed - let's assume this is Jest internal and it should be `require`
248240
{browser: false, require: true};
249241
}
250242

251-
function createImportsResolveOptions(conditions: Array<string> | undefined) {
252-
return {
253-
conditions: conditions
254-
? [...conditions, 'default']
255-
: ['node', 'require', 'default'],
256-
};
257-
}
258-
259243
// if it's a relative import or an absolute path, imports/exports are ignored
260244
const shouldIgnoreRequestForExports = (path: string) =>
261245
path.startsWith('.') || isAbsolute(path);

yarn.lock

+5-22
Original file line numberDiff line numberDiff line change
@@ -12895,8 +12895,7 @@ __metadata:
1289512895
jest-util: "workspace:^"
1289612896
jest-validate: "workspace:^"
1289712897
resolve: ^1.20.0
12898-
resolve.exports: ^1.1.1
12899-
resolve.imports: ^2.0.3
12898+
resolve.exports: ^2.0.0
1290012899
slash: ^3.0.0
1290112900
tsd-lite: ^0.6.0
1290212901
languageName: unknown
@@ -16415,13 +16414,6 @@ __metadata:
1641516414
languageName: node
1641616415
linkType: hard
1641716416

16418-
"pattern-key-compare@npm:^2.0.0":
16419-
version: 2.0.0
16420-
resolution: "pattern-key-compare@npm:2.0.0"
16421-
checksum: cded15070cddbc5ef7b97c1b91371bcf59ff931f8afe383d2323f935891e6c4517bd76154f5edc2b1ab53c6fbeeb0711b9db43af592064482d0a9ccf03dd507c
16422-
languageName: node
16423-
linkType: hard
16424-
1642516417
"pend@npm:~1.2.0":
1642616418
version: 1.2.0
1642716419
resolution: "pend@npm:1.2.0"
@@ -18359,19 +18351,10 @@ __metadata:
1835918351
languageName: node
1836018352
linkType: hard
1836118353

18362-
"resolve.exports@npm:^1.1.1":
18363-
version: 1.1.1
18364-
resolution: "resolve.exports@npm:1.1.1"
18365-
checksum: 485aa10082eb388a569d696e17ad7b16f4186efc97dd34eadd029d95b811f21ffee13b1b733198bb4584dbb3cb296aa6f141835221fb7613b9606b84f1386655
18366-
languageName: node
18367-
linkType: hard
18368-
18369-
"resolve.imports@npm:^2.0.3":
18370-
version: 2.0.3
18371-
resolution: "resolve.imports@npm:2.0.3"
18372-
dependencies:
18373-
pattern-key-compare: ^2.0.0
18374-
checksum: 155ae4a32ccc1da7ad12b88f6c748dd1e038092838e537de1066248c32a197b42489810da6070bb2bd0dd954e8abbe841b09282c0806c5493b2e49e8f7e29632
18354+
"resolve.exports@npm:^2.0.0":
18355+
version: 2.0.0
18356+
resolution: "resolve.exports@npm:2.0.0"
18357+
checksum: d8bee3b0cc0a0ae6c8323710983505bc6a3a2574f718e96f01e048a0f0af035941434b386cc9efc7eededc5e1199726185c306ec6f6a1aa55d5fbad926fd0634
1837518358
languageName: node
1837618359
linkType: hard
1837718360

0 commit comments

Comments
 (0)