Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: resolve wildcard subpath patterns in package exports#890

Merged
gioboa merged 2 commits into
module-federation:mainfrom
jonasfrisell:fix/exports-wildcard-subpath-resolution
Jul 9, 2026
Merged

fix: resolve wildcard subpath patterns in package exports#890
gioboa merged 2 commits into
module-federation:mainfrom
jonasfrisell:fix/exports-wildcard-subpath-resolution

Conversation

@jonasfrisell

Copy link
Copy Markdown
Contributor

Problem

Sharing a workspace package whose package.json uses wildcard exports subpaths (the layout shadcn/ui and Base UI generate) fails in dev. Given:

{
  "exports": {
    "./components/*": "./components/*.tsx"
  }
}

the generated loadShare module throws:

The requested module '...' does not provide an export named 'Button'

(same for Select, CommandDialog, etc.). The shared module exposes only a default export.

Root Cause

getPackageExportsTarget (src/utils/packageUtils.ts) resolves a subpath against the exports map by exact-key lookup only (record[subpath]). For @scope/ui/components/button, subpath is ./components/button, but the map only contains the wildcard key ./components/*, so the lookup returns undefined, resolution falls back to index.js, and named-export detection yields [].

The chain that surfaces it:

getSharedNamedExports
  -> getPackageNamedExports        // require() fails on a .tsx source
  -> getEsmNamedExports
  -> getPackageEsmEntryPath
  -> getInstalledPackageEntry({ resolveSubpathWithRequire: false })
  -> getPackageExportsTarget       // returns undefined for the wildcard subpath

Fix

Replace the exact-key lookup in getPackageExportsTarget with Node's exports subpath pattern matching (PACKAGE_IMPORTS_EXPORTS_RESOLVE): the exact key wins first, otherwise the best pattern by PATTERN_KEY_COMPARE (longest literal patternBase, then longest key), and the captured patternMatch is substituted into the resolved target. Two small helpers do this (matchExportsSubpath and substituteExportsWildcard), 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.

  • Verified the 5 new tests fail on main (exact-key lookup) and pass with the fix; the 13 pre-existing tests pass unchanged.
  • Full suite: 636 passing. pnpm fmt.check and pnpm typecheck clean.

Impact / Scope

Reproduction

Any workspace monorepo where a shared package's package.json exports uses a wildcard subpath pointing at source (e.g. "./components/*": "./components/*.tsx") and lists the package in shared. Importing any component subpath from the federated module then throws in dev.

@pkg-pr-new

pkg-pr-new Bot commented Jul 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@module-federation/vite@890

commit: 09280e9

@gioboa gioboa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests With Different Frameworks

Image

@gioboa gioboa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jonasfrisell for your great improvement πŸš€

@gioboa gioboa merged commit 0a9ff20 into module-federation:main Jul 9, 2026
25 of 27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants