Skip to content

Commit

Permalink
fix react-server-dom-webpack cache invalidation (#55287)
Browse files Browse the repository at this point in the history
### 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
  • Loading branch information
ForsakenHarmony authored Sep 13, 2023
1 parent fe797c1 commit d64bc4c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 32 deletions.
15 changes: 8 additions & 7 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 4 additions & 3 deletions packages/next/src/server/app-render/use-flight-response.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down
67 changes: 45 additions & 22 deletions packages/next/src/server/lib/router-utils/setup-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
Expand Down Expand Up @@ -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
}

Expand All @@ -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) {
Expand Down Expand Up @@ -380,8 +382,6 @@ async function startWatcher(opts: SetupOpts) {
sendHmrDebounce()
}

const clearCache = (filePath: string) => deleteCache(filePath)

async function loadPartialManifest<T>(
name: string,
pageName: string,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -583,6 +584,7 @@ async function startWatcher(opts: SetupOpts) {
currentEntriesHandlingResolve = undefined
}
}

handleEntries().catch((err) => {
console.error(err)
process.exit(1)
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -759,7 +779,7 @@ async function startWatcher(opts: SetupOpts) {
'server',
NEXT_FONT_MANIFEST + '.json'
)
await clearCache(fontManifestPath)
deleteCache(fontManifestPath)
await writeFile(
fontManifestPath,
JSON.stringify(
Expand All @@ -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),
Expand Down Expand Up @@ -847,6 +867,7 @@ async function startWatcher(opts: SetupOpts) {
await currentEntriesHandling
await writeBuildManifest()
await writeAppBuildManifest()
await writeFallbackBuildManifest()
await writePagesManifest()
await writeAppPathsManifest()
await writeMiddlewareManifest()
Expand Down Expand Up @@ -1008,6 +1029,7 @@ async function startWatcher(opts: SetupOpts) {
await loadPagesManifest('_error')

await writeBuildManifest()
await writeFallbackBuildManifest()
await writePagesManifest()
await writeMiddlewareManifest()
await writeOtherManifests()
Expand Down Expand Up @@ -1118,6 +1140,7 @@ async function startWatcher(opts: SetupOpts) {
}

await writeBuildManifest()
await writeFallbackBuildManifest()
await writePagesManifest()
await writeMiddlewareManifest()
await writeOtherManifests()
Expand Down

0 comments on commit d64bc4c

Please sign in to comment.