You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
When using tinyglobby get wrong components files order #831
I added a sort function where you can add your logic to sort your components, the test added in the PR using simple ascending/descending sorts, I guess with this callback applied before generating the output record should be fine for your use case, maybe we can use asc sort by default.
We can also iterate later using the dirs order to apply 2 sorts, first using the dirs order and then by name for each dirs entry.
I added a sort function where you can add your logic to sort your components, the test added in the PR using simple ascending/descending sorts, I guess with this callback applied before generating the output record should be fine for your use case, maybe we can use asc sort by default.
We can also iterate later using the dirs order to apply 2 sorts, first using the dirs order and then by name for each dirs entry.
This would be extremely helpful, I was looking for something like this in the source code this evening and tried to setup a custom resolver to replace the glob / dir feature, but it’s not really good, especially for developing where files are added, renamed and removed. Really appreciate your work on a fix
Disadvantage of adding it to tinyglobby, you can not replace this dependency with another glob lib in the future.
Is there a big performance diff. in running the glob for each dir/glob speratly vs. all at once? If not, running the glob search sequentially could also result in a deterministic output.
Yeah, since we also have a watcher, we need to sort the files at least when adding files, maybe we need some helper function at tiny-globby, it is using picomatch or maybe just add some logic there here: we only need the matched patterns and the picomatch options.
Will try another approach, running N scans (1 per pattern/glob) instead 1 global. Maybe we can also move sync to async scan, I need to review the code and the perf. We still have the same issue about the watcher when adding new files.
@samuelweiSuperchupuDev/tinyglobby#168 (new helper function at tinyglobby abstracting picomatch usage, this way, if tinyglobby changes its internal matcher, this repo should be also fine => don't require to add picomatch or switch to xxxmatch when tinyglob changes it internally)
I'm working on the PR to include the abstraction using Generator, here some work on my local, the sortFilesByGlobPrecedence should go to src/core/fs/glob.ts, and should use the new compileGlob helper function at SuperchupuDev/tinyglobby#168:
// src/core/context.tsexportclassContext{// other entriesprivate*sortFilesByGlobPrecedence(files: Iterable<string>): Generator<string,undefined,void>{constprocessedFiles=newSet<string>()constallFiles=Array.from(files)const{ globs, ...rest}=this.optionsfor(constglobofglobs){constisMatch=picomatch(glob,rest)for(constfileofallFiles){if(!processedFiles.has(file)&&isMatch(file)){processedFiles.add(file)yieldfile}}}}private*preparePaths(): Generator<string,undefined,void>{if(this.options.sortByGlob){yield*this.sortFilesByGlobPrecedence(this._componentPaths)}else{yield*this._componentPaths}}private*applyPathsSorting(files: Iterable<string>): Generator<string,undefined,void>{constgenerator=this.options.sortif(generator){const{
root,
globs,
globsExclude,
resolvedDirs,}=this.optionsyield*generator({
root,
globs,
globsExclude,
resolvedDirs,},Array.from(files))}else{yield*files}}privateupdateComponentNameMap(){this._componentNameMap={}const{ prefix, excludeNames, allowOverrides }=this.optionsfor(constpathofthis.applyPathsSorting(this.preparePaths())){constfileName=getNameFromFilePath(path,this.options)constname=prefix
? `${pascalCase(prefix)}${pascalCase(fileName)}`
: pascalCase(fileName)if(isExclude(name,excludeNames)){debug.components('exclude',name)continue}if(this._componentNameMap[name]&&!allowOverrides){console.warn(`[unplugin-vue-components] component "${name}"(${path}) has naming conflicts with other components, ignored.`)continue}this._componentNameMap[name]={as: name,from: path,}}}}
and here the new sort and sortByGlob options:
// src/types.ts/** * Plugin options. */exportinterfaceOptions{// other options/** * Enable `globs` sort for scanned files. * * `unplugin-vue-components` using `tinyglobby` to scan files, which is non-deterministic. */sortByGlob?: true/** * Generator to provide files before preparing the components. * * @param options The resolved options. * @param files The scanned files. */sort?: (options: Pick<ResolvedOptions,'root'|'resolvedDirs'|'globs'|'globsExclude'>,files: string[])=>Generator<string,undefined,void>}
@samuelwei@SoulLyoko my PR here updated using pkg-pr-new from compileGlobs PR at tinyglobby, I'm going to add pkg-pr-new also to unplugin-vue-components.
@samuelwei I'm preparing a new PR at tinyglobby (a lot of changes on main = feat: add sort support) 🤞 , I tried with a new package but I need to copy almost every module at tinyglobby... 🤦
There are some edge cases where the tinyglobby consumer may want to sort the files:
tinyglobby: sort first applying pattern, inside the resulting string[] for each pattern the consumer may want to sort them asc or desc (pattern-asc and pattern-desc respectivelly) => this is the default behavior at tinyglobby
unplugin-vue-components: sort the patterns and the resulting string[] for each pattern => in your screenshot, won't work at tinyglobby since the patterns won't be sorted and then the files will preserve the dirs => first resources/js (sort the files inside in ascending) then resources/custom/js (sort the files inside in ascending)
Suppose we have this: dirs: ['a', 'b'] where a contains a/a.vue and a/b.vue ad b contains b/a.vue and b/b.vue, the result will be:
tinygloby:
pattern: [a/a.vue, a/b.vue, b/a.vue, b/b.vue] or any combination of a.vue and b.vue (first ones from a and last ones from b), for example: [a/b.vue, a/a.vue, b/b.vue, b/a.vue] => tinyglobby will create in this case 2 arrays, one per pattern and before returning them will sort the files if using pattern-asc/desc
pattern-desc: [a/b.vue, a/a.vue, b/b.vue, b/a.vue]; if you change the dirs (patterns) to be ['b', 'a'] then [b/b.vue, b/a.vue, a/b.vue, a/a.vue]
pattern-asc: [a/a.vue, a/b.vue, b/a.vue, b/b.vue]; if you change the dirs (patterns) be ['b', 'a'] then [b/a.vue, b/b.vue, a/b.vue, a/a.vue]
unplugin-vue-components: since we need to override components when using pattern, we need to sort also the patterns (patterns built from dirs)
Hi! Thanks @userquin for all the work on #905 and SuperchupuDev/tinyglobby#189. Since the tinyglobby PR seems to be stuck on package-size concerns, I tried a smaller fix that doesn't touch the glob layer at all: #922.
The idea: in Context.updateComponentNameMap(), sort the collected paths by the index of the first dirs/globs entry each path matches (with picomatch, already a dependency) and break ties with localeCompare. Later dirs then override earlier ones under allowOverrides, as they did with fast-glob in v28. Because the sort runs each time the map is rebuilt, files added through HMR follow the same priority. It's about 15 lines plus tests, with no new option and no dependency change.
I see it as a complement to #905, not a replacement. It fixes the default order, and the sort option from #905 could still be layered on top later for anyone who wants different ordering inside a glob.
We've been running this as a patch in Valaxy (which layers core → theme → addons → user component dirs), and it would let us drop our vendored copy. Would the maintainers be open to taking it?
Activity
ilyaliao commentedon Jun 20, 2025
However, according to the
fast-globdocs, results are returned in arbitrary order.samuelwei commentedon Sep 25, 2025
I also need a deterministic method for overwriting, whereby one directory should take precedence over the other.
userquin commentedon Sep 25, 2025
I added a sort function where you can add your logic to sort your components, the test added in the PR using simple ascending/descending sorts, I guess with this callback applied before generating the output record should be fine for your use case, maybe we can use asc sort by default.
We can also iterate later using the dirs order to apply 2 sorts, first using the dirs order and then by name for each dirs entry.
userquin commentedon Sep 25, 2025
This is not fine if the arbitrary order breaks for example the dirs/globs order. Looks like the globs being sorted in ascending order.
I'm going to check tinyglobby, looks like a bug to me.
userquin commentedon Sep 25, 2025
SuperchupuDev/tinyglobby#166
samuelwei commentedon Sep 25, 2025
This would be extremely helpful, I was looking for something like this in the source code this evening and tried to setup a custom resolver to replace the glob / dir feature, but it’s not really good, especially for developing where files are added, renamed and removed. Really appreciate your work on a fix
userquin commentedon Sep 25, 2025
I'll try adding a new option at tinyglobby, unimport and unplugin-auto-import may have the same issue.
/cc @danielroe @antfu
userquin commentedon Sep 25, 2025
@samuelwei I'm checking this: SuperchupuDev/tinyglobby#166 (comment)
userquin commentedon Sep 25, 2025
PR sent to tinyglobby 🤞 SuperchupuDev/tinyglobby#167
samuelwei commentedon Sep 26, 2025
Disadvantage of adding it to tinyglobby, you can not replace this dependency with another glob lib in the future.
Is there a big performance diff. in running the glob for each dir/glob speratly vs. all at once? If not, running the glob search sequentially could also result in a deterministic output.
userquin commentedon Sep 26, 2025
Yeah, since we also have a watcher, we need to sort the files at least when adding files, maybe we need some helper function at tiny-globby, it is using picomatch or maybe just add some logic there here: we only need the matched patterns and the picomatch options.
Will try another approach, running N scans (1 per pattern/glob) instead 1 global. Maybe we can also move sync to async scan, I need to review the code and the perf. We still have the same issue about the watcher when adding new files.
I also need to check unimport and unplugin-auto-import (not the same problem, since unimport has an order where you can apply some priority => not sure if it is a nuxt thingy) => unimport type => usage https://github.com/elk-zone/elk/blob/main/nuxt.config.ts#L90-L94
userquin commentedon Sep 26, 2025
@samuelwei SuperchupuDev/tinyglobby#168 (new helper function at tinyglobby abstracting picomatch usage, this way, if tinyglobby changes its internal matcher, this repo should be also fine => don't require to add picomatch or switch to xxxmatch when tinyglob changes it internally)
I'm working on the PR to include the abstraction using
Generator, here some work on my local, thesortFilesByGlobPrecedenceshould go tosrc/core/fs/glob.ts, and should use the newcompileGlobhelper function at SuperchupuDev/tinyglobby#168:and here the new
sortandsortByGloboptions:userquin commentedon Sep 26, 2025
@samuelwei @SoulLyoko my PR here updated using pkg-pr-new from
compileGlobsPR at tinyglobby, I'm going to add pkg-pr-new also to unplugin-vue-components.samuelwei commentedon Oct 27, 2025
@userquin Any progress on this?
userquin commentedon Oct 27, 2025
No, the PR here should be ready (pr moved to draft), awaiting tinyglobby: SuperchupuDev/tinyglobby#168 (comment)
samuelwei commentedon Jan 19, 2026
@userquin I guess tinyglobby is not going to add this feature. Can we still get a fix in this project?
userquin commentedon Jan 27, 2026
@samuelwei I'm preparing a new PR at tinyglobby (a lot of changes on main =
feat: add sort support) 🤞 , I tried with a new package but I need to copy almost every module at tinyglobby... 🤦SuperchupuDev/tinyglobby#189
userquin commentedon Jan 28, 2026
can anyone check using
"unplugin-vue-components": "https://pkg.pr.new/unplugin-vue-components@905"? the vite-vue3 example is working hereSoulLyoko commentedon Jan 28, 2026
I will try it in my project later🤞
userquin commentedon Jan 28, 2026
Read the new sort option 🙏 , you need to configure the correct dirs, check the sort test snapshot and the tests, use
sort: 'pattern':SoulLyoko commentedon Jan 28, 2026
@userquin I test my project with
sort: 'pattern', it works well👍samuelwei commentedon Jan 28, 2026
@userquin Tested in my project with
sort: 'pattern', it workedHowever I do not understand whats the difference between pattern, pattern-asc and pattern-desc
Using
sort: 'pattern'andsort: 'pattern-desc'worked,sort: 'pattern-asc'didn't work in my case where I wanted to overwrite a component.userquin commentedon Jan 28, 2026
There are some edge cases where the tinyglobby consumer may want to sort the files:
pattern-ascandpattern-descrespectivelly) => this is the default behavior at tinyglobbyresources/js(sort the files inside in ascending) thenresources/custom/js(sort the files inside in ascending)Suppose we have this:
dirs: ['a', 'b']where a containsa/a.vueanda/b.vueadbcontainsb/a.vueandb/b.vue, the result will be:pattern: [a/a.vue,a/b.vue,b/a.vue,b/b.vue] or any combination ofa.vueandb.vue(first ones fromaand last ones fromb), for example: [a/b.vue,a/a.vue,b/b.vue,b/a.vue] => tinyglobby will create in this case 2 arrays, one per pattern and before returning them will sort the files if usingpattern-asc/descpattern-desc: [a/b.vue,a/a.vue,b/b.vue,b/a.vue]; if you change the dirs (patterns) to be['b', 'a']then [b/b.vue,b/a.vue,a/b.vue,a/a.vue]pattern-asc: [a/a.vue,a/b.vue,b/a.vue,b/b.vue]; if you change the dirs (patterns) be['b', 'a']then [b/a.vue,b/b.vue,a/b.vue,a/a.vue]pattern, we need to sort also the patterns (patterns built from dirs)YunYouJun commentedon Oct 19, 2026
Hi! Thanks @userquin for all the work on #905 and SuperchupuDev/tinyglobby#189. Since the tinyglobby PR seems to be stuck on package-size concerns, I tried a smaller fix that doesn't touch the glob layer at all: #922.
The idea: in
Context.updateComponentNameMap(), sort the collected paths by the index of the firstdirs/globsentry each path matches (with picomatch, already a dependency) and break ties withlocaleCompare. Later dirs then override earlier ones underallowOverrides, as they did with fast-glob in v28. Because the sort runs each time the map is rebuilt, files added through HMR follow the same priority. It's about 15 lines plus tests, with no new option and no dependency change.I see it as a complement to #905, not a replacement. It fixes the default order, and the
sortoption from #905 could still be layered on top later for anyone who wants different ordering inside a glob.We've been running this as a patch in Valaxy (which layers core → theme → addons → user component dirs), and it would let us drop our vendored copy. Would the maintainers be open to taking it?