Skip to content

fix: order components by dirs/globs priority - #922

Open
YunYouJun wants to merge 1 commit into
unplugin:mainfrom
YunYouJun:fix/component-override-order-by-globs
Open

YunYouJun wants to merge 1 commit into
unplugin:mainfrom
YunYouJun:fix/component-override-order-by-globs

Conversation

@YunYouJun

Copy link
Copy Markdown
Contributor

Description

Since the switch from fast-glob to tinyglobby, the component that wins under allowOverrides depends on the order tinyglobby walks the filesystem. That order is not the order of dirs/globs (#831). Files added later through the watcher (HMR) also land at the end of the Set, so a lower-priority file that is re-added can override a higher-priority one.

This PR leaves the glob layer alone. Context.updateComponentNameMap() now sorts component paths by the index of the first configured glob they match and uses localeCompare to break ties:

  • Later dirs/globs override earlier ones under allowOverrides: true. This matches the fast-glob behavior from v28.
  • Without allowOverrides, the first dir wins and later duplicates get the existing warning.
  • The order is decided each time the map is rebuilt. Files added by HMR therefore follow the same priority as the initial scan.
  • Paths that match no glob (for example, ones passed to addComponents directly) sort last.
  • Each update compiles one picomatch matcher per glob and computes priorities once, so the cost stays O(n log n). picomatch is already a dependency.

The change is 15 lines in src/core/context.ts. It adds no option and no dependency change.

Relation to #905

#905 by @userquin adds a sort option on top of tinyglobby's proposed sort support (SuperchupuDev/tinyglobby#189). This PR is meant as a dependency-free complement to it. It fixes the default order, and #905's sort option could still be layered on top for users who want a different order inside each glob.

Linked Issues

Closes #831

Additional context

Tests (test/search.test.ts, fixtures in test/fixtures/override/{base,theme,user}):

  • dirs: ['base', 'theme', 'user']: user/Button.vue wins, and base/Badge.vue is still resolved.
  • globs in reverse path order (user, theme, base): base/Button.vue wins, which shows that the globs order decides and the path order does not.
  • After the initial scan, removeComponents + addComponents on the lower-priority theme/Button.vue (simulating HMR): user/Button.vue still wins.
  • Without allowOverrides, the first dir wins.

Without the context.ts change, 3 of the 4 new tests fail. vitest, eslint and tsgo all pass, and no existing snapshot changed.

Context: Valaxy layers components from core → theme → addons → user dirs and relies on later dirs winning. It currently vendors a patched copy of this plugin for that reason alone. This PR upstreams that patch.

Sort component paths by the index of the first glob they match before
building the name map, so the configured order decides which component
wins under `allowOverrides`, both for the initial scan and for files
added later through the watcher.

Closes unplugin#831
@YunYouJun
YunYouJun requested a review from antfu as a code owner October 19, 2026 13:40
@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@pkg-pr-new

pkg-pr-new Bot commented Oct 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/unplugin-vue-components@922

commit: 56da5f6

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.

When using tinyglobby get wrong components files order

1 participant