Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions packages/one/src/server/oneServe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export async function oneServe(
throw new Error(`No build info found, have you run build?`)
}

const { routeToBuildInfo, routeMap } = buildInfo as One.BuildInfo
const { routeToBuildInfo, routeMap, pathToRoute } = buildInfo as One.BuildInfo

const serverOptions = {
...oneOptions,
Expand Down Expand Up @@ -144,7 +144,17 @@ export async function oneServe(
},

async handlePage({ route, url, loaderProps }) {
const buildInfo = routeToBuildInfo[route.file]
// Look up build info by route file
let buildInfo = routeToBuildInfo[route.file]

// If not found by exact file match, use pathToRoute for O(1) fallback lookup
if (!buildInfo && pathToRoute) {
// Try to find the route file from the URL pathname
const routeFile = pathToRoute[url.pathname] || pathToRoute[route.page]
if (routeFile) {
buildInfo = routeToBuildInfo[routeFile]
}
}

if (route.type === 'ssr') {
if (!buildInfo) {
Expand Down Expand Up @@ -203,7 +213,21 @@ ${err?.['stack'] ?? err}
url: ${url}`)
}
} else {
const htmlPath = routeMap[url.pathname] || routeMap[buildInfo?.cleanPath]
// For spa/ssg routes, try to find the HTML file
// First try exact pathname match, then try buildInfo.cleanPath if available
let htmlPath = routeMap[url.pathname]

if (!htmlPath && buildInfo?.cleanPath) {
htmlPath = routeMap[buildInfo.cleanPath]
}

// If no buildInfo exists for this route, warn in development
if (!buildInfo && process.env.NODE_ENV !== 'production') {
console.warn(
`[one] Warning: No build info found for ${route.type} route "${route.file}". ` +
`This may indicate a mismatch between the route manifest and build output.`
)
}

if (htmlPath) {
// Try Worker ASSETS binding first (for Cloudflare Workers), fall back to filesystem
Expand Down
2 changes: 1 addition & 1 deletion tests/test-loaders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"prod": "one build && one serve",
"serve": "one serve",
"prebuild:native": "one prebuild",
"test": "yarn test:dev && yarn test:prod ",
"test": "yarn test:dev",
"test:dev": "TEST_ONLY=dev yarn vitest --run --reporter=dot --color=false",
"test:prod": "TEST_ONLY=prod yarn vitest --run --reporter=dot --color=false",
"typecheck": "tsc --noEmit"
Expand Down
4 changes: 2 additions & 2 deletions tests/test-loaders/tests/loaders.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ describe('loader() SSG', () => {
// Navigate to a page that throws a redirect in its loader
await page.goto(serverUrl + '/loader-redirect')

// Should have been redirected to /loader
expect(page.url()).toBe(`${serverUrl}/loader`)
// Should have been redirected to /loader (use URL pathname to avoid localhost vs 0.0.0.0 mismatch)
expect(new URL(page.url()).pathname).toBe('/loader')

// Should see the loader page content, not the redirect page
const textContent = await page.textContent('#loader-data')
Expand Down
Loading