-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First item is always resolved when export map target is Array (even if non-existent) #20
Comments
I am under the impression that this is exactly how node works? The code here is manually picked from node. I don't think they have that. |
So sorry, just now realizing this code is pulled from the node algorithm, and the issue is an upstream one (and, apparently, expected behavior? 🙄) Edit: thanks for the quick reply. This actually explains why I was having issues with another bundler—that's what got me searching for this package in the first place lol. Edit-edit: I promise this wasn't an XY problem—I actually did (mis-)read the spec first... |
From what I gather, the “spec” was I think just a random idea years ago. Then folks implemented it. And figured out that it was super complex to do everything. And decided to rip things out. Personally, I feel like conditions do a good job already at pointing to one file or another. And whether files currently exist or not isn’t something that should be related to the public API of a package. You may like https://github.com/wooorm/package-exports, which attempt to lint package exports! |
Nice! That would have saved me a headache. Although I noticed the rule that would have caught this says 'Many tools don't support this... Heh, including node! I reckon most folks want this for simulating the 'CJS' semantics of guessing extensions, but this actually has a valid use-case in a cross-platform environment. I left my 2 cents on their issue, but I'll just have to go back to the drawing board on my end 🤷 |
ok, well a) don’t restore extension guessing, b) you’re talking about “conditionally resolve”, and that’s something that conditions already do? c) you can use asterisks as well.
(prefix and suffix here just an example. depends on your actual files what values to use) |
This sounds more like you have a question on how best to expose your package’s API. That’s fine. But then I need you to provide me the input files. Then I can help you. |
I appreciate your offer to help, especially considering I didn't even open an issue in the right repo 😅 I think I know an approach, but it's not elegant. There's really not a good way to achieve what I'm aiming for. I've got two apps which share a multiple cross-platform internal packages. One, the UI library, is compiled before consumption. In effect, this just means that all built files end with Many of the package modules are pure react, using only platform-agnostic APIs. For these files, I would like just to have a single Some of the modules, however, have unique implementations for each platform. For these, I would like to have Setting aside the wisdom of extension guessing, this is the exports map I hoped to use: "exports": {
".": {
"types": [
"./src/index.ts",
"./src/index.tsx"
],
"browser": [
"./src/index.web.ts",
"./src/index.web.tsx",
"./src/index.ts",
"./src/index.tsx"
],
"ios": [
"./src/index.ios.ts",
"./src/index.ios.tsx",
"./src/index.ts",
"./src/index.tsx"
],
"android": [
"./src/index.android.ts",
"./src/index.android.tsx",
"./src/index.ts",
"./src/index.tsx"
],
"native": [
"./src/index.native.ts",
"./src/index.native.tsx",
"./src/index.ts",
"./src/index.tsx"
],
"default": [
"./src/index.ts",
"./src/index.tsx"
]
},
"./*": {
"types": [
"./src/*.ts",
"./src/*/index.ts",
"./src/*.tsx",
"./src/*/index.tsx"
],
"browser": [
"./src/*.web.ts",
"./src/*/index.web.ts",
"./src/*.web.tsx",
"./src/*/index.web.tsx",
"./src/*.ts",
"./src/*/index.ts",
"./src/*.tsx",
"./src/*/index.tsx"
],
"ios": [
"./src/*.ios.ts",
"./src/*/index.ios.ts",
"./src/*.ios.tsx",
"./src/*/index.ios.tsx",
"./src/*.ts",
"./src/*/index.ts",
"./src/*.tsx",
"./src/*/index.tsx"
],
"android": [
"./src/*.android.ts",
"./src/*/index.android.ts",
"./src/*.android.tsx",
"./src/*/index.android.tsx",
"./src/*.ts",
"./src/*/index.ts",
"./src/*.tsx",
"./src/*/index.tsx"
],
"native": [
"./src/*.native.ts",
"./src/*/index.native.ts",
"./src/*.native.tsx",
"./src/*/index.native.tsx",
"./src/*.ts",
"./src/*/index.ts",
"./src/*.tsx",
"./src/*/index.tsx"
],
"default": [
"./src/*.ts",
"./src/*/index.ts",
"./src/*.tsx",
"./src/*/index.tsx"
]
}
} and here is an example of the file tree: packages/app/src
├── providers.tsx # Should be resolved the same regardless of platform, including types
├── fonts
│ ├── Inter.web.ts # Should be exclusively resolved by Webpack
│ ├── Inter.native.ts # Should be exclusively resolved by Metro
│ └── Inter.ts # Should be exclusively resolved by Typescript
└── index.ts # Should be resolved the same regardless of platform, including types Now, TypeScript is smart enough to know that if I import Unless you see something I'm missing, the only option is to 1) transpile all packages and 2) explicitly export all modules with a EDIT: To add an additional wrinkle, Metro Bundler does not respect platform extensions when using the |
Can you post all the files you have in I would recommend taking some time to think about what you want to expose. |
Current Behavior
Given the following exports map:
Where
./non-existent.js
does not exist on disk, the following holds true:Expected Behavior
"example/c" should resolve to "example/d.js" when "./non-existent.js" is not found.
Reproduction
I've added tests that cover both cases in the associated PR. The first passes, but the second fails the
strictEqual
assertion.Additional Info
I took a swing at fixing this, but no luck. The
packageExportsResolve
algorithm callsresolvePackageTarget
when it finds a match in theexports
field.resolvePackageTarget
does check iftarget
is an array, but it greedily accepts the first entry unless it throwsERR_INVALID_PACKAGE_TARGET
. However, the target technically is a valid target—it just doesn't point to an existing file.My first thought was to call
fileExists(resolved)
just before returning out of the loop on line 540, and, iffalse
, continue the loop to the next item. Unfortunately that didn't seem to work for some reason.import-meta-resolve/lib/resolve.js
Line 540 in 411516a
My next thought was that one of the other resolver functions was returning a result before the
packageExportsResolve
ever gets called, short-circuiting it.Unfortunately, it seems I can't get any of my breakpoints to fire when I run it in the debugger, nor can I get any
console.log
calls to print to the terminal. Any ideas what might be going on here?The text was updated successfully, but these errors were encountered: