A route table maintained by hand next to a directory of route files, forgotten on average once a month.
const modules = import.meta.glob('./routes/*.tsx')
const routes = Object.entries(modules).map(([path, load]) => ({
path: '/' + path.match(/./routes/(.+).tsx$/)[1],
component: lazy(load),
}))
// the glob is resolved at build time, so the chunks are
// still split per route — this is not a runtime require.
The build-time resolution is what makes this safe: the bundler sees every match and can split them, unlike a dynamic import with a computed path. The convention it introduces is that a filename is a URL, which is fine until a route needs a parameter or an unusual character — at which point an explicit table for the exceptions, layered over the glob, is clearer than encoding rules in filenames.