Skip to content

Watcher updates move routes out of scan order #27

Closed

Description

@everton-dgn

#14 made the initial scan sort route files, but the watcher path still changes the order. _addRoute removes an existing entry and pushes the new one to the end, and new files are always appended. The Vite plugin calls updateRoute on every change event (src/vite/fs-watcher.ts) and, with types enabled, regenerates the declaration, which is rewritten because its order changed. Saving a route file during development reorders the generated .d.ts and the virtual manifest even when nothing about the routes changed. In a project that commits the declaration, editing a route file that isn't already last in the manifest shows up as a diff, and a later build puts the order back.

Reproduction

Verified with filesystem-routing@0.4.0 from npm on Node 24.22.1. Save as repro.mjs in a project that depends on filesystem-routing@0.4.0 and run node repro.mjs:

import { mkdtempSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { PageFileSystemRouter } from 'filesystem-routing'

const dir = mkdtempSync(join(tmpdir(), 'routes-'))
for (const name of ['about', 'contact', 'zebra']) {
  writeFileSync(join(dir, `${name}.tsx`), 'export default () => null;')
}
const router = new PageFileSystemRouter({ dir, extensions: ['tsx'] })
const paths = () => router.routes.map(route => route.path).join(' ')

await router.getRoutes()
console.log('scan:          ', paths())

// What the Vite watcher does when about.tsx is saved.
await router.updateRoute(join(dir, 'about.tsx'))
console.log('after update:  ', paths())

writeFileSync(join(dir, 'blog.tsx'), 'export default () => null;')
await router.addRoute(join(dir, 'blog.tsx'))
console.log('after add:     ', paths())

const fresh = new PageFileSystemRouter({ dir, extensions: ['tsx'] })
console.log('fresh scan:    ', (await fresh.getRoutes()).map(route => route.path).join(' '))

Output:

scan:           /about /contact /zebra
after update:   /contact /zebra /about
after add:      /contact /zebra /about /blog
fresh scan:     /about /blog /contact /zebra

Expected

After any sequence of watcher events, router.routes has the same order as a fresh scan of the same files: an updated route keeps its position, and a new route is inserted where the sorted scan would put it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions