vite-plugin-pages icon indicating copy to clipboard operation
vite-plugin-pages copied to clipboard

[...all] match problem

Open Amorites opened this issue 2 years ago • 5 comments

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.

Amorites avatar Aug 18 '22 15:08 Amorites

~~fixed in v0.26.0~~

hannoeru avatar Sep 02 '22 15:09 hannoeru

@hannoer I upgraded the dependency, but the performance is still the same as before

repro: https://github.com/Amorites/vite-plugin-pages-all-issue

Amorites avatar Sep 07 '22 03:09 Amorites

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))
}

achaphiv avatar Sep 15 '22 09:09 achaphiv

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 avatar Sep 15 '22 22:09 achaphiv

@achaphiv This is not releated to this issue, please open a new issue and provide a minimal reproduction.

hannoeru avatar Sep 19 '22 06:09 hannoeru