vite-plugin-pages
vite-plugin-pages copied to clipboard
[...all] match problem
Describe the bug
I have file structure like:
├── pages
│ ├── [...all].vue
│ ├── hi
│ │ └── [...all].vue
│ ├── index.vue
│ └── README.md
localhost:5173/hi
is supposed to display pages/hi/[...all].vue
but display pages/[...all].vue
localhost:5173/hi/
and localhost:5173/hi/foo
works as expected.
Not really sure this is a bug or feature, but src/pages/[...all].vue -> /* (/non-existent-page)
described in the doc is a little bit ambiguous.
Reproduction
https://github.com/Amorites/vite-plugin-pages-all-issue
System Info
System:
OS: Linux 3.10 CentOS Linux 7 (Core)
CPU: (12) x64 AMD EPYC 7702P 64-Core Processor
Memory: 18.63 GB / 23.39 GB
Container: Yes
Shell: 5.8.1 - /usr/local/bin/zsh
Binaries:
Node: 16.16.0 - ~/n/bin/node
npm: 6.14.4 - /usr/bin/npm
Used Package Manager
pnpm
Validations
- [X] Follow the Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Check that this is a concrete bug. For Q&A please open a GitHub Discussion.
- [X] The provided reproduction is a minimal reproducible example of the bug.
~~fixed in v0.26.0~~
@hannoer I upgraded the dependency, but the performance is still the same as before
repro: https://github.com/Amorites/vite-plugin-pages-all-issue
For v0.26.0, I noticed the all
route was in the middle of the routes array. So I had to move it to the end.
const catchAllIndex = routes.findIndex((it) => it.name === 'all')
if (catchAllIndex !== routes.length - 1) {
routes.push(...routes.splice(catchAllIndex, 1))
}
Hmm, after further testing, it seems children are not being sorted with dynamic routes last.
So to fix it, I had to do the following in my vite.config.ts
Pages({
routeStyle: 'nuxt',
onRoutesGenerated(routes: Array<VueRoute>) {
function isCatchAll(route: VueRoute) {
return route.name === 'all'
}
function isDynamic(route: VueRoute) {
return route.path.includes(':')
}
function fixAll(routes: Array<VueRoute>) {
routes.sort((a, b) => {
if (isCatchAll(a)) {
return 1
}
if (isCatchAll(b)) {
return -1
}
const aDynamic = isDynamic(a)
const bDynamic = isDynamic(b)
if (aDynamic !== bDynamic) {
// Non-dynamic first
return aDynamic ? 1 : -1
}
const aSize = a.path.length
const bSize = b.path.length
if (aSize !== bSize) {
// Longest length first
return bSize - aSize
}
return a.path.localeCompare(b.path)
})
routes.forEach(fix)
}
function fix(route: VueRoute) {
if (route.children) {
fixAll(route.children)
}
}
fixAll(routes)
return routes
},
})
@achaphiv This is not releated to this issue, please open a new issue and provide a minimal reproduction.