mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
447b416f4d
### What? When running a [multi-zone](https://github.com/vercel/next.js/tree/canary/examples/with-zones) app in dev, guest app pages would infinitely reload if you change the basePath of the host app to the default one (omit basePath settings in next.config.js) (empty string `""` as per Next.js docs). ### Why? The HMR upgrade request would fail and get caught into a retry loop. In the multi-zone case, they fail because the upgrade request would be sent again for a request that had already been upgraded. This resulted in a "server.handleUpgrade() was called more than once with the same socket" error, causing the upgrade request to fail. Every time a retry occurred, the page would trigger a full refresh since certain HMR errors cause the browser to reload. ### How? This ensures the upgrade handler only responds to requests that match the configured basePath (considering when there is no basePath). Default basePath for Next.js applications it's an empty string `""`. Ref: https://nextjs.org/docs/app/api-reference/next-config-js/basePath Other fixes & updates related to the bug: - Updated test apps to avoid having issues regarding client & server mismatch for dates - Added default use case in e2e tests, where you have a default Next.js application where the basePath it's the default one and a guest app that it's being routed by the main one through Next.js rewrites. Closes NEXT-1797 Fixes #59161 Fixes #56615 Fixes #54454 --------- Co-authored-by: Zack Tanner <zacktanner@gmail.com>
48 lines
1.3 KiB
JavaScript
48 lines
1.3 KiB
JavaScript
const next = require('next')
|
|
const path = require('path')
|
|
const { parse } = require('url')
|
|
const http = require('http')
|
|
|
|
;(async () => {
|
|
const requestHandlers = new Map()
|
|
const dev = process.env.NODE_ENV !== 'production'
|
|
|
|
for (const appName of ['host', 'guest']) {
|
|
const appDir = path.join(__dirname, 'apps', appName)
|
|
const nextApp = next({
|
|
dir: appDir,
|
|
dev,
|
|
})
|
|
|
|
await nextApp.prepare()
|
|
const handler = nextApp.getRequestHandler()
|
|
requestHandlers.set(appName, handler)
|
|
}
|
|
|
|
const server = http.createServer(async (req, res) => {
|
|
const appName = req.url.startsWith('/guest') ? 'guest' : 'host'
|
|
const handler = requestHandlers.get(appName)
|
|
|
|
if (!handler) {
|
|
res.statusCode = 404
|
|
return res.end('not found')
|
|
}
|
|
|
|
try {
|
|
await handler(req, res, parse(req.url, true))
|
|
} catch (err) {
|
|
console.error(err)
|
|
res.statusCode = 500
|
|
res.end('internal error')
|
|
}
|
|
})
|
|
const parsedPort = Number(process.env.PORT)
|
|
const port = !isNaN(parsedPort) ? parsedPort : 3000
|
|
|
|
server.listen(port, () => {
|
|
const actualPort = server.address().port
|
|
console.log(` ▲ Next.js\n - Local: http://localhost:${actualPort}`)
|
|
console.log(`- Next mode: ${dev ? 'development' : process.env.NODE_ENV}`)
|
|
})
|
|
})()
|