Closed gpickell closed 1 year ago
Hey, thanks, but what you're calling x*y
and x*y*z
isn't actually supported by Node.js nor the algorithm. Verified this with Node 18.x and 19.4:
{
"name": "foo",
"exports": {
// any value variation
"./features/*/*/index": "./import/*/dist/*.mjs"
}
}
import * as foo from 'foo/features/foo/bar/index';
console.log({ foo });
//=> Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './features/foo/bar/index' is not defined by "exports" in /.../node_modules/foo/package.json imported from /.../test.mjs
Perhaps it was supported at one time, but as is/has been the case a few times, it must have changed 🙃
For now, at least, only 1 *
may be present in the entry name, whose matched substring may be repeated as many times as defined in the resolved value. For example:
pkg = {
name: "hello",
exports: {
"./features/*": "./build/esm/*/spacer/*.mjs"
}
};
resolve(pkg, "hello/features/foo/bar");
//=> "./build/esm/foo/bar/spacer/foo/bar.mjs"
What does currently need fixing is:
*
-matched substring as many times as referenced in the target value
9
*
character anywhere within the entry name, not just at the end (which used to be the only supported pattern, lol)
22
As a significant portion of this PR appears to be here for /*/*/
support, I'm going to close this & lean on the other PRs to solve both of these.
Sorry for the long delay, but thank you!
I'm confused because I just replicated it again in a bare mono repo: https://github.com/gpickell/wildcards-in-exports-demo
works in node v18.12.1 and v19.4.0 (remember to run yarn):
It works because your target directory structure matches the import statements in a way that the structure is reassembled correctly based on 1st replacement. It's not working because it's matching 2 *
characters:
// Real:
// node_modules/package-a/dist/folder/spacer/sub/index.mjs
// node_modules/package-a/dist/folder/index.mjs
Patterns: {
"./*/index": "./dist/*/index.mjs",
"./*/*/index": "./dist/*/spacer/*/index.mjs"
}
// Imports
// ---
import "package-a/folder/index"; // "*"
// matches "./*/index" ~> "*" = "folder" ~> "./dist/<folder>/index.mjs"
import "package-a/folder/spacer/sub/index";
// ALSO matches "./*/index" ~> "*" = "folder/spacer/sub" ~> "./dist/<folder/spacer/sub>/index.mjs"
If you remove the "./*/index"
export pattern (and the "package-a/folder/index"
import, which we agree is meant to match that export) then you'll see that the second "./*/*/index"
export pattern correctly throws an error:
// Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './folder/spacer/sub/index' is not defined by "exports" in /.../node_modules/package-a/package.json imported from /.../index.mjs
This is all because the "./*/index"
pattern is present, was a match, and the resolver algorithm didn't find any other (valid) longer matches, so kept "./*/index"
as the candidate. You can swap the order of your package-a
exports and see the same thing happen, since pattern-order doesn't matter.
Yup. Fears alleviated. I agree with the above synopsis.
Related issue: #9