Skip to content

Commit

Permalink
refactor(resolve): use resolve.exports for imports (#13777)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeed committed Jan 17, 2023
1 parent 8ef8c20 commit ea5e47e
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 85 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -6,7 +6,7 @@
- `[jest-config, jest-worker]` Use `os.availableParallelism` if available to calculate number of workers to spawn ([#13738](https://github.com/facebook/jest/pull/13738))
- `[@jest/globals, jest-mock]` Add `jest.replaceProperty()` that replaces property value ([#13496](https://github.com/facebook/jest/pull/13496))
- `[jest-haste-map]` ignore Sapling vcs directories (`.sl/`) ([#13674](https://github.com/facebook/jest/pull/13674))
- `[jest-resolve]` Support subpath imports ([#13705](https://github.com/facebook/jest/pull/13705), [#13723](https://github.com/facebook/jest/pull/13723))
- `[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))
- `[jest-runtime]` Add `jest.isolateModulesAsync` for scoped module initialization of asynchronous functions ([#13680](https://github.com/facebook/jest/pull/13680))
- `[jest-runtime]` Add `jest.isEnvironmentTornDown` function ([#13698](https://github.com/facebook/jest/pull/13698))
- `[jest-test-result]` Added `skipped` and `focused` status to `FormattedTestResult` ([#13700](https://github.com/facebook/jest/pull/13700))
Expand Down
3 changes: 1 addition & 2 deletions packages/jest-resolve/package.json
Expand Up @@ -24,8 +24,7 @@
"jest-util": "workspace:^",
"jest-validate": "workspace:^",
"resolve": "^1.20.0",
"resolve.exports": "^1.1.1",
"resolve.imports": "^2.0.3",
"resolve.exports": "^2.0.0",
"slash": "^3.0.0"
},
"devDependencies": {
Expand Down
9 changes: 1 addition & 8 deletions packages/jest-resolve/src/__tests__/resolve.test.ts
Expand Up @@ -397,14 +397,7 @@ describe('findNodeModule', () => {
basedir: path.resolve(importsRoot, './foo-import/index.js'),
conditions: [],
});
}).toThrow(
expect.objectContaining({
code: 'ERR_PACKAGE_IMPORT_NOT_DEFINED',
message: expect.stringMatching(
/^Package import specifier "#something-else" is not defined in package/,
),
}),
);
}).toThrow('Missing "#something-else" specifier in "foo-import" package');
});
});
});
Expand Down
88 changes: 36 additions & 52 deletions packages/jest-resolve/src/defaultResolver.ts
Expand Up @@ -8,11 +8,7 @@
import {dirname, isAbsolute, resolve as pathResolve} from 'path';
import pnpResolver from 'jest-pnp-resolver';
import {SyncOpts as UpstreamResolveOptions, sync as resolveSync} from 'resolve';
import {
Options as ResolveExportsOptions,
resolve as resolveExports,
} from 'resolve.exports';
import {resolve as resolveImports} from 'resolve.imports';
import * as resolve from 'resolve.exports';
import {
findClosestPackageJson,
isDirectory,
Expand Down Expand Up @@ -148,28 +144,26 @@ function getPathInModule(

const pkg = readPackageCached(closestPackageJson);

const resolved = resolveImports(
{
base: options.basedir,
content: pkg,
path: dirname(closestPackageJson),
},
path,
createImportsResolveOptions(options.conditions),
const resolved = resolve.imports(
pkg,
path as resolve.Imports.Entry,
createResolveOptions(options.conditions),
);

if (!resolved) {
if (resolved) {
const target = resolved[0];
return target.startsWith('.')
? // internal relative filepath
pathResolve(dirname(closestPackageJson), target)
: // this is an external module, re-resolve it
defaultResolver(target, options);
}

if (pkg.imports) {
throw new Error(
'`imports` exists, but no results - this is a bug in Jest. Please report an issue',
);
}

if (resolved.startsWith('.')) {
return pathResolve(dirname(closestPackageJson), resolved);
}

// this is an external module, re-resolve it
return defaultResolver(resolved, options);
}

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

if (pkg.name === moduleName && pkg.exports) {
const subpath = segments.join('/') || '.';

const resolved = resolveExports(
if (pkg.name === moduleName) {
const resolved = resolve.exports(
pkg,
subpath,
(segments.join('/') || '.') as resolve.Exports.Entry,
createResolveOptions(options.conditions),
);

if (!resolved) {
if (resolved) {
return pathResolve(dirname(closestPackageJson), resolved[0]);
}

if (pkg.exports) {
throw new Error(
'`exports` exists, but no results - this is a bug in Jest. Please report an issue',
);
}

return pathResolve(dirname(closestPackageJson), resolved);
}
}

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

if (pkg.exports) {
const subpath = segments.join('/') || '.';

const resolved = resolveExports(
pkg,
subpath,
createResolveOptions(options.conditions),
);
const resolved = resolve.exports(
pkg,
(segments.join('/') || '.') as resolve.Exports.Entry,
createResolveOptions(options.conditions),
);

if (!resolved) {
throw new Error(
'`exports` exists, but no results - this is a bug in Jest. Please report an issue',
);
}
if (resolved) {
return pathResolve(dirname(packageJsonPath), resolved[0]);
}

return pathResolve(dirname(packageJsonPath), resolved);
if (pkg.exports) {
throw new Error(
'`exports` exists, but no results - this is a bug in Jest. Please report an issue',
);
}
}
}
Expand All @@ -241,21 +233,13 @@ function getPathInModule(

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

function createImportsResolveOptions(conditions: Array<string> | undefined) {
return {
conditions: conditions
? [...conditions, 'default']
: ['node', 'require', 'default'],
};
}

// if it's a relative import or an absolute path, imports/exports are ignored
const shouldIgnoreRequestForExports = (path: string) =>
path.startsWith('.') || isAbsolute(path);
27 changes: 5 additions & 22 deletions yarn.lock
Expand Up @@ -12895,8 +12895,7 @@ __metadata:
jest-util: "workspace:^"
jest-validate: "workspace:^"
resolve: ^1.20.0
resolve.exports: ^1.1.1
resolve.imports: ^2.0.3
resolve.exports: ^2.0.0
slash: ^3.0.0
tsd-lite: ^0.6.0
languageName: unknown
Expand Down Expand Up @@ -16415,13 +16414,6 @@ __metadata:
languageName: node
linkType: hard

"pattern-key-compare@npm:^2.0.0":
version: 2.0.0
resolution: "pattern-key-compare@npm:2.0.0"
checksum: cded15070cddbc5ef7b97c1b91371bcf59ff931f8afe383d2323f935891e6c4517bd76154f5edc2b1ab53c6fbeeb0711b9db43af592064482d0a9ccf03dd507c
languageName: node
linkType: hard

"pend@npm:~1.2.0":
version: 1.2.0
resolution: "pend@npm:1.2.0"
Expand Down Expand Up @@ -18359,19 +18351,10 @@ __metadata:
languageName: node
linkType: hard

"resolve.exports@npm:^1.1.1":
version: 1.1.1
resolution: "resolve.exports@npm:1.1.1"
checksum: 485aa10082eb388a569d696e17ad7b16f4186efc97dd34eadd029d95b811f21ffee13b1b733198bb4584dbb3cb296aa6f141835221fb7613b9606b84f1386655
languageName: node
linkType: hard

"resolve.imports@npm:^2.0.3":
version: 2.0.3
resolution: "resolve.imports@npm:2.0.3"
dependencies:
pattern-key-compare: ^2.0.0
checksum: 155ae4a32ccc1da7ad12b88f6c748dd1e038092838e537de1066248c32a197b42489810da6070bb2bd0dd954e8abbe841b09282c0806c5493b2e49e8f7e29632
"resolve.exports@npm:^2.0.0":
version: 2.0.0
resolution: "resolve.exports@npm:2.0.0"
checksum: d8bee3b0cc0a0ae6c8323710983505bc6a3a2574f718e96f01e048a0f0af035941434b386cc9efc7eededc5e1199726185c306ec6f6a1aa55d5fbad926fd0634
languageName: node
linkType: hard

Expand Down

0 comments on commit ea5e47e

Please sign in to comment.