Skip to content

Commit

Permalink
fix(lookupNodeModuleSubpath): handle conditions and nested exports (#210
Browse files Browse the repository at this point in the history
)

Co-authored-by: Pooya Parsa <pooya@pi0.io>
  • Loading branch information
productdevbook and pi0 authored Jan 11, 2024
1 parent 5213717 commit 4cb88e5
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 22 deletions.
28 changes: 15 additions & 13 deletions src/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,21 +206,23 @@ function _findSubpath(subpath: string, exports: PackageJson["exports"]) {
return subpath;
}

const flattenedExports = _flattenExports(exports);
const [foundPath] =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
flattenedExports.find(([_, resolved]) => resolved === subpath) || [];

return foundPath;
return _flattenExports(exports).find((p) => p.fsPath === subpath)?.subpath;
}

function _flattenExports(
exports: Exclude<PackageJson["exports"], string>,
path?: string,
) {
return Object.entries(exports).flatMap(([key, value]) =>
typeof value === "string"
? [[path ?? key, value]]
: _flattenExports(value, path ?? key),
);
parentSubpath = "./",
): { subpath: string; fsPath: string; condition?: string }[] {
return Object.entries(exports).flatMap(([key, value]) => {
const [subpath, condition] = key.startsWith(".")
? [key.slice(1), undefined]
: [undefined, key];
const _subPath = joinURL(parentSubpath, subpath);
// eslint-disable-next-line unicorn/prefer-ternary
if (typeof value === "string") {
return [{ subpath: _subPath, fsPath: value, condition }];
} else {
return _flattenExports(value, _subPath);
}
});
}
1 change: 1 addition & 0 deletions test/fixture/package/node_modules/postgres/cjs/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions test/fixture/package/node_modules/postgres/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixture/package/node_modules/postgres/src/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion test/fixture/package/node_modules/subpaths/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 21 additions & 8 deletions test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,26 +108,39 @@ describe("lookupNodeModuleSubpath", () => {
const r = (p: string) => new URL(p, import.meta.url).toString();

const tests = [
// Resolve with exports
{
name: "resolves with exports field",
input: r("fixture/package/node_modules/subpaths/lib/subpath.mjs"),
name: "resolves with exports field (root)",
input: r("fixture/package/node_modules/subpaths/dist/index.mjs"),
output: "./",
},
{
name: "resolves with exports field (subpath)",
input: r("fixture/package/node_modules/subpaths/dist/subpath.mjs"),
output: "./subpath",
},
{
name: "resolves with fallback subpath guess",
name: "resolves with exports field (with conditions)",
input: r("fixture/package/node_modules/postgres/src/index.js"),
output: "./",
},
// Fallbacks
{
name: "resolves with fallback (non resolved module)",
input: r("fixture/package/node_modules/alien/lib/subpath.json5"),
output: "./lib/subpath.json5",
},
{
name: "resolves with fallback subpath guess (non existing file)",
input: r("fixture/package/node_modules/subpaths/foo/bar.mjs"),
output: "./foo/bar.mjs",
},
// Invalid
{
name: "ignores invalid paths",
input: r("/foo/bar/lib/subpath.mjs"),
output: undefined,
},
{
name: "resolves main export",
input: r("fixture/package/node_modules/subpaths/foo/bar.mjs"),
output: "./foo/bar.mjs",
},
{
name: "resolves main export",
input: r("fixture/package/node_modules/subpaths/"),
Expand Down

0 comments on commit 4cb88e5

Please sign in to comment.