fix react-server-dom-webpack
cache invalidation (#55287)
### What? Webpack wrapped the external import in a new module, making `require.cache` invalidation impossible. This also adds a basic fallback manifest for turbopack. Closes WEB-1522
This commit is contained in:
parent
fe797c1074
commit
d64bc4c619
3 changed files with 57 additions and 32 deletions
15
.github/CODEOWNERS
vendored
15
.github/CODEOWNERS
vendored
|
@ -28,10 +28,11 @@
|
|||
|
||||
# Tooling & Telemetry
|
||||
|
||||
/packages/next/src/build/ @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
/packages/next/src/telemetry/ @timneutkens @ijjk @shuding @padmaia
|
||||
/packages/next-swc/ @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
Cargo.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
Cargo.lock @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
/.cargo/config.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
/.config/nextest.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
/packages/next/src/build/ @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
/packages/next/src/server/lib/router-utils/setup-dev.ts @timneutkens @ijjk @shuding @huozhi @feedthejim @ztanner @wyattjoh @vercel/web-tooling
|
||||
/packages/next/src/telemetry/ @timneutkens @ijjk @shuding @padmaia
|
||||
/packages/next-swc/ @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
Cargo.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
Cargo.lock @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
/.cargo/config.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
/.config/nextest.toml @timneutkens @ijjk @shuding @huozhi @vercel/web-tooling
|
||||
|
|
|
@ -21,9 +21,10 @@ export function useFlightResponse(
|
|||
return flightResponseRef.current
|
||||
}
|
||||
// react-server-dom-webpack/client.edge must not be hoisted for require cache clearing to work correctly
|
||||
const {
|
||||
createFromReadableStream,
|
||||
} = require(`react-server-dom-webpack/client.edge`)
|
||||
const { createFromReadableStream } = process.env.NEXT_MINIMAL
|
||||
? // @ts-ignore
|
||||
__non_webpack_require__(`react-server-dom-webpack/client.edge`)
|
||||
: require(`react-server-dom-webpack/client.edge`)
|
||||
|
||||
const [renderStream, forwardStream] = req.tee()
|
||||
const res = createFromReadableStream(renderStream, {
|
||||
|
|
|
@ -103,7 +103,10 @@ import {
|
|||
TurboPackConnectedAction,
|
||||
} from '../../dev/hot-reloader-types'
|
||||
import { debounce } from '../../utils'
|
||||
import { deleteCache } from '../../../build/webpack/plugins/nextjs-require-cache-hot-reloader'
|
||||
import {
|
||||
deleteAppClientCache,
|
||||
deleteCache,
|
||||
} from '../../../build/webpack/plugins/nextjs-require-cache-hot-reloader'
|
||||
import { normalizeMetadataRoute } from '../../../lib/metadata/get-metadata-route'
|
||||
|
||||
const wsServer = new ws.Server({ noServer: true })
|
||||
|
@ -311,20 +314,18 @@ async function startWatcher(opts: SetupOpts) {
|
|||
async function processResult(
|
||||
result: TurbopackResult<WrittenEndpoint>
|
||||
): Promise<TurbopackResult<WrittenEndpoint>> {
|
||||
for (const file of result.serverPaths
|
||||
.map((p) => path.join(distDir, p))
|
||||
.concat([
|
||||
// We need to clear the chunk cache in react
|
||||
require.resolve(
|
||||
'next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js'
|
||||
),
|
||||
// And this redirecting module as well
|
||||
require.resolve(
|
||||
'next/dist/compiled/react-server-dom-webpack/client.edge.js'
|
||||
),
|
||||
])) {
|
||||
const hasAppPaths = result.serverPaths.some((p) =>
|
||||
p.startsWith('server/app')
|
||||
)
|
||||
|
||||
if (hasAppPaths) {
|
||||
deleteAppClientCache()
|
||||
}
|
||||
|
||||
for (const file of result.serverPaths.map((p) => path.join(distDir, p))) {
|
||||
deleteCache(file)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -337,6 +338,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
moduleTrace?: Array<{ moduleName: string }>
|
||||
stack?: string
|
||||
}
|
||||
|
||||
const errors = new Map<string, HmrError>()
|
||||
for (const [, issueMap] of issues) {
|
||||
for (const [key, issue] of issueMap) {
|
||||
|
@ -380,8 +382,6 @@ async function startWatcher(opts: SetupOpts) {
|
|||
sendHmrDebounce()
|
||||
}
|
||||
|
||||
const clearCache = (filePath: string) => deleteCache(filePath)
|
||||
|
||||
async function loadPartialManifest<T>(
|
||||
name: string,
|
||||
pageName: string,
|
||||
|
@ -482,6 +482,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
if (payload) sendHmr('endpoint-change', page, payload)
|
||||
}
|
||||
}
|
||||
|
||||
function clearChangeSubscription(page: string) {
|
||||
const subscription = changeSubscriptions.get(page)
|
||||
if (subscription) {
|
||||
|
@ -583,6 +584,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
currentEntriesHandlingResolve = undefined
|
||||
}
|
||||
}
|
||||
|
||||
handleEntries().catch((err) => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
|
@ -665,7 +667,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
async function writeBuildManifest(): Promise<void> {
|
||||
const buildManifest = mergeBuildManifests(buildManifests.values())
|
||||
const buildManifestPath = path.join(distDir, BUILD_MANIFEST)
|
||||
await clearCache(buildManifestPath)
|
||||
deleteCache(buildManifestPath)
|
||||
await writeFile(
|
||||
buildManifestPath,
|
||||
JSON.stringify(buildManifest, null, 2),
|
||||
|
@ -696,12 +698,30 @@ async function startWatcher(opts: SetupOpts) {
|
|||
)
|
||||
}
|
||||
|
||||
async function writeFallbackBuildManifest(): Promise<void> {
|
||||
const fallbackBuildManifest = mergeBuildManifests(
|
||||
[buildManifests.get('_app'), buildManifests.get('_error')].filter(
|
||||
Boolean
|
||||
) as BuildManifest[]
|
||||
)
|
||||
const fallbackBuildManifestPath = path.join(
|
||||
distDir,
|
||||
`fallback-${BUILD_MANIFEST}`
|
||||
)
|
||||
deleteCache(fallbackBuildManifestPath)
|
||||
await writeFile(
|
||||
fallbackBuildManifestPath,
|
||||
JSON.stringify(fallbackBuildManifest, null, 2),
|
||||
'utf-8'
|
||||
)
|
||||
}
|
||||
|
||||
async function writeAppBuildManifest(): Promise<void> {
|
||||
const appBuildManifest = mergeAppBuildManifests(
|
||||
appBuildManifests.values()
|
||||
)
|
||||
const appBuildManifestPath = path.join(distDir, APP_BUILD_MANIFEST)
|
||||
await clearCache(appBuildManifestPath)
|
||||
deleteCache(appBuildManifestPath)
|
||||
await writeFile(
|
||||
appBuildManifestPath,
|
||||
JSON.stringify(appBuildManifest, null, 2),
|
||||
|
@ -712,7 +732,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
async function writePagesManifest(): Promise<void> {
|
||||
const pagesManifest = mergePagesManifests(pagesManifests.values())
|
||||
const pagesManifestPath = path.join(distDir, 'server', PAGES_MANIFEST)
|
||||
await clearCache(pagesManifestPath)
|
||||
deleteCache(pagesManifestPath)
|
||||
await writeFile(
|
||||
pagesManifestPath,
|
||||
JSON.stringify(pagesManifest, null, 2),
|
||||
|
@ -727,7 +747,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
'server',
|
||||
APP_PATHS_MANIFEST
|
||||
)
|
||||
await clearCache(appPathsManifestPath)
|
||||
deleteCache(appPathsManifestPath)
|
||||
await writeFile(
|
||||
appPathsManifestPath,
|
||||
JSON.stringify(appPathsManifest, null, 2),
|
||||
|
@ -743,7 +763,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
distDir,
|
||||
'server/middleware-manifest.json'
|
||||
)
|
||||
await clearCache(middlewareManifestPath)
|
||||
deleteCache(middlewareManifestPath)
|
||||
await writeFile(
|
||||
middlewareManifestPath,
|
||||
JSON.stringify(middlewareManifest, null, 2),
|
||||
|
@ -759,7 +779,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
'server',
|
||||
NEXT_FONT_MANIFEST + '.json'
|
||||
)
|
||||
await clearCache(fontManifestPath)
|
||||
deleteCache(fontManifestPath)
|
||||
await writeFile(
|
||||
fontManifestPath,
|
||||
JSON.stringify(
|
||||
|
@ -780,7 +800,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
distDir,
|
||||
'react-loadable-manifest.json'
|
||||
)
|
||||
await clearCache(loadableManifestPath)
|
||||
deleteCache(loadableManifestPath)
|
||||
await writeFile(
|
||||
loadableManifestPath,
|
||||
JSON.stringify({}, null, 2),
|
||||
|
@ -847,6 +867,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
await currentEntriesHandling
|
||||
await writeBuildManifest()
|
||||
await writeAppBuildManifest()
|
||||
await writeFallbackBuildManifest()
|
||||
await writePagesManifest()
|
||||
await writeAppPathsManifest()
|
||||
await writeMiddlewareManifest()
|
||||
|
@ -1008,6 +1029,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
await loadPagesManifest('_error')
|
||||
|
||||
await writeBuildManifest()
|
||||
await writeFallbackBuildManifest()
|
||||
await writePagesManifest()
|
||||
await writeMiddlewareManifest()
|
||||
await writeOtherManifests()
|
||||
|
@ -1118,6 +1140,7 @@ async function startWatcher(opts: SetupOpts) {
|
|||
}
|
||||
|
||||
await writeBuildManifest()
|
||||
await writeFallbackBuildManifest()
|
||||
await writePagesManifest()
|
||||
await writeMiddlewareManifest()
|
||||
await writeOtherManifests()
|
||||
|
|
Loading…
Reference in a new issue