Skip to content

Commit

Permalink
fix manifest load errors when using assetPrefix (#55416)
Browse files Browse the repository at this point in the history
### What?
`_devPagesManifest.json` and `_devMiddlewareManifest.json` will fail to load when using an asset prefix. In conjunction with i18n, this causes the app to get caught in an infinite load loop. 

### Why?
We're expecting these paths to be exact matches but when there's an assetPrefix specified, they won't be matched. 

### How?
This copies similar behavior to how we handle [`webpack-hmr`](https://github.com/vercel/next.js/blob/2e2211d27b3f0ff1cff5553453df4cf391996163/packages/next/src/server/lib/router-server.ts#L681) by doing a partial match on the URL when serving it

Closes NEXT-1618
Fixes #55389
  • Loading branch information
ztanner committed Sep 15, 2023
1 parent 2e2211d commit 1e33253
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
8 changes: 6 additions & 2 deletions packages/next/src/client/page-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import { isDynamicRoute } from '../shared/lib/router/utils/is-dynamic'
import { parseRelativeUrl } from '../shared/lib/router/utils/parse-relative-url'
import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-slash'
import { createRouteLoader, getClientBuildManifest } from './route-loader'
import {
DEV_CLIENT_PAGES_MANIFEST,
DEV_MIDDLEWARE_MANIFEST,
} from '../shared/lib/constants'

declare global {
interface Window {
Expand Down Expand Up @@ -60,7 +64,7 @@ export default class PageLoader {
return window.__DEV_PAGES_MANIFEST.pages
} else {
this.promisedDevPagesManifest ||= fetch(
`${this.assetPrefix}/_next/static/development/_devPagesManifest.json`
`${this.assetPrefix}/_next/static/development/${DEV_CLIENT_PAGES_MANIFEST}`
)
.then((res) => res.json())
.then((manifest: { pages: string[] }) => {
Expand Down Expand Up @@ -94,7 +98,7 @@ export default class PageLoader {
// TODO: Decide what should happen when fetching fails instead of asserting
// @ts-ignore
this.promisedMiddlewareMatchers = fetch(
`${this.assetPrefix}/_next/static/${this.buildId}/_devMiddlewareManifest.json`
`${this.assetPrefix}/_next/static/${this.buildId}/${DEV_MIDDLEWARE_MANIFEST}`
)
.then((res) => res.json())
.then((matchers: MiddlewareMatcher[]) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/server/lib/router-utils/setup-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1919,7 +1919,7 @@ async function startWatcher(opts: SetupOpts) {
async function requestHandler(req: IncomingMessage, res: ServerResponse) {
const parsedUrl = url.parse(req.url || '/')

if (parsedUrl.pathname === clientPagesManifestPath) {
if (parsedUrl.pathname?.includes(clientPagesManifestPath)) {
res.statusCode = 200
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.end(
Expand All @@ -1932,7 +1932,7 @@ async function startWatcher(opts: SetupOpts) {
return { finished: true }
}

if (parsedUrl.pathname === devMiddlewareManifestPath) {
if (parsedUrl.pathname?.includes(devMiddlewareManifestPath)) {
res.statusCode = 200
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.end(JSON.stringify(serverFields.middleware?.matchers || []))
Expand Down
28 changes: 28 additions & 0 deletions test/development/basic/asset-prefix.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { join } from 'path'
import { createNextDescribe } from 'e2e-utils'
import { check } from 'next-test-utils'

createNextDescribe(
'asset-prefix',
{
files: join(__dirname, 'asset-prefix'),
},
({ next }) => {
it('should load the app properly without reloading', async () => {
const browser = await next.browser('/')
await browser.eval(`window.__v = 1`)

expect(await browser.elementByCss('div').text()).toBe('Hello World')

await check(async () => {
const logs = await browser.log()
const hasError = logs.some((log) =>
log.message.includes('Failed to fetch')
)
return hasError ? 'error' : 'success'
}, 'success')

expect(await browser.eval(`window.__v`)).toBe(1)
})
}
)
20 changes: 20 additions & 0 deletions test/development/basic/asset-prefix/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const ASSET_PREFIX = 'asset-prefix'

module.exports = {
assetPrefix: ASSET_PREFIX,
i18n: {
locales: ['en-US'],
defaultLocale: 'en-US',
},
async rewrites() {
return {
beforeFiles: [
{
source: `/:locale/${ASSET_PREFIX}/_next/:path*`,
destination: '/_next/:path*',
locale: false,
},
],
}
},
}
5 changes: 5 additions & 0 deletions test/development/basic/asset-prefix/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react'

export default function Page() {
return <div>Hello World</div>
}

0 comments on commit 1e33253

Please sign in to comment.