fix: resolve wildcard subpath patterns in package exports#890
Merged
gioboa merged 2 commits intoJul 9, 2026
Merged
Conversation
commit: |
gioboa
approved these changes
Jul 9, 2026
gioboa
left a comment
Collaborator
There was a problem hiding this comment.
Thanks @jonasfrisell for your great improvement π
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Problem
Sharing a workspace package whose
package.jsonuses wildcardexportssubpaths (the layout shadcn/ui and Base UI generate) fails in dev. Given:{ "exports": { "./components/*": "./components/*.tsx" } }the generated
loadSharemodule throws:(same for
Select,CommandDialog, etc.). The shared module exposes only adefaultexport.Root Cause
getPackageExportsTarget(src/utils/packageUtils.ts) resolves a subpath against theexportsmap by exact-key lookup only (record[subpath]). For@scope/ui/components/button,subpathis./components/button, but the map only contains the wildcard key./components/*, so the lookup returnsundefined, resolution falls back toindex.js, and named-export detection yields[].The chain that surfaces it:
Fix
Replace the exact-key lookup in
getPackageExportsTargetwith Node'sexportssubpath pattern matching (PACKAGE_IMPORTS_EXPORTS_RESOLVE): the exact key wins first, otherwise the best pattern byPATTERN_KEY_COMPARE(longest literalpatternBase, then longest key), and the capturedpatternMatchis substituted into the resolved target. Two small helpers do this (matchExportsSubpathandsubstituteExportsWildcard), covering string, conditional-object, and fallback-array targets.Tests
Adds 5 cases to
src/utils/__tests__/packageUtils.test.ts: wildcard resolution into string, conditional-object, and fallback-array targets, plus longest-prefix and equal-base tiebreak selection.main(exact-key lookup) and pass with the fix; the 13 pre-existing tests pass unchanged.pnpm fmt.checkandpnpm typecheckclean.Impact / Scope
.(root) path is untouched.virtualShared_preBuild.tsbut not theexports-map resolution inpackageUtils.tswhere this gap lived.Reproduction
Any workspace monorepo where a shared package's
package.jsonexportsuses a wildcard subpath pointing at source (e.g."./components/*": "./components/*.tsx") and lists the package inshared. Importing any component subpath from the federated module then throws in dev.