Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,69 +1,12 @@
import type { webpack } from 'next/dist/compiled/webpack/webpack'
import { deleteCache } from '../../../server/dev/require-cache'
import { clearModuleContext } from '../../../server/web/sandbox'
import { realpathSync } from '../../../lib/realpath'
import path from 'path'
import isError from '../../../lib/is-error'
import { clearManifestCache } from '../../../server/load-manifest'

type Compiler = webpack.Compiler
type WebpackPluginInstance = webpack.WebpackPluginInstance

const originModules = [
require.resolve('../../../server/require'),
require.resolve('../../../server/load-components'),
require.resolve('../../../server/next-server'),
require.resolve('next/dist/compiled/next-server/app-page.runtime.dev.js'),
require.resolve('next/dist/compiled/next-server/app-route.runtime.dev.js'),
require.resolve('next/dist/compiled/next-server/pages.runtime.dev.js'),
require.resolve('next/dist/compiled/next-server/pages-api.runtime.dev.js'),
]

const RUNTIME_NAMES = ['webpack-runtime', 'webpack-api-runtime']

function deleteFromRequireCache(filePath: string) {
try {
filePath = realpathSync(filePath)
} catch (e) {
if (isError(e) && e.code !== 'ENOENT') throw e
}
const mod = require.cache[filePath]
if (mod) {
// remove the child reference from the originModules
for (const originModule of originModules) {
const parent = require.cache[originModule]
if (parent) {
const idx = parent.children.indexOf(mod)
if (idx >= 0) parent.children.splice(idx, 1)
}
}
// remove parent references from external modules
for (const child of mod.children) {
child.parent = null
}
delete require.cache[filePath]
return true
}
return false
}

export function deleteAppClientCache() {
deleteFromRequireCache(
require.resolve('next/dist/compiled/next-server/app-page.runtime.dev.js')
)
deleteFromRequireCache(
require.resolve(
'next/dist/compiled/next-server/app-page-experimental.runtime.dev.js'
)
)
}

export function deleteCache(filePath: string) {
// try to clear it from the fs cache
clearManifestCache(filePath)

deleteFromRequireCache(filePath)
}

const PLUGIN_NAME = 'NextJsRequireCacheHotReloader'

// This plugin flushes require.cache after emitting the files. Providing 'hot reloading' of server files.
Expand Down
5 changes: 1 addition & 4 deletions packages/next/src/server/dev/hot-reloader-turbopack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ import { BLOCKED_PAGES } from '../../shared/lib/constants'
import { getOverlayMiddleware } from '../../client/components/react-dev-overlay/server/middleware-turbopack'
import { PageNotFoundError } from '../../shared/lib/utils'
import { debounce } from '../utils'
import {
deleteAppClientCache,
deleteCache,
} from '../../build/webpack/plugins/nextjs-require-cache-hot-reloader'
import { deleteAppClientCache, deleteCache } from './require-cache'
import {
clearAllModuleContexts,
clearModuleContext,
Expand Down
46 changes: 46 additions & 0 deletions packages/next/src/server/dev/require-cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import isError from '../../lib/is-error'
import { realpathSync } from '../../lib/realpath'
import { clearManifestCache } from '../load-manifest'

function deleteFromRequireCache(filePath: string) {
try {
filePath = realpathSync(filePath)
} catch (e) {
if (isError(e) && e.code !== 'ENOENT') throw e
}
const mod = require.cache[filePath]
if (mod) {
// remove the child reference from all parent modules
for (const parent of Object.values(require.cache)) {
if (parent?.children) {
const idx = parent.children.indexOf(mod)
if (idx >= 0) parent.children.splice(idx, 1)
}
}
// remove parent references from external modules
for (const child of mod.children) {
child.parent = null
}
delete require.cache[filePath]
return true
}
return false
}

export function deleteAppClientCache() {
deleteFromRequireCache(
require.resolve('next/dist/compiled/next-server/app-page.runtime.dev.js')
)
deleteFromRequireCache(
require.resolve(
'next/dist/compiled/next-server/app-page-experimental.runtime.dev.js'
)
)
}

export function deleteCache(filePath: string) {
// try to clear it from the fs cache
clearManifestCache(filePath)

deleteFromRequireCache(filePath)
}
2 changes: 1 addition & 1 deletion packages/next/src/server/dev/turbopack/manifest-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
import { join, posix } from 'path'
import { readFile, writeFile } from 'fs/promises'
import type { SetupOpts } from '../../lib/router-utils/setup-dev-bundler'
import { deleteCache } from '../../../build/webpack/plugins/nextjs-require-cache-hot-reloader'
import { deleteCache } from '../require-cache'
import { writeFileAtomic } from '../../../lib/fs/write-atomic'
import { isInterceptionRouteRewrite } from '../../../lib/generate-interception-routes-rewrites'
import {
Expand Down
14 changes: 0 additions & 14 deletions packages/next/src/server/lib/render-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@ let initializations: Record<
> = {}

let sandboxContext: undefined | typeof import('../web/sandbox/context')
let requireCacheHotReloader:
| undefined
| typeof import('../../build/webpack/plugins/nextjs-require-cache-hot-reloader')

if (process.env.NODE_ENV !== 'production') {
sandboxContext = require('../web/sandbox/context')
requireCacheHotReloader = require('../../build/webpack/plugins/nextjs-require-cache-hot-reloader')
}

export function clearAllModuleContexts() {
Expand All @@ -37,16 +33,6 @@ export function clearModuleContext(target: string) {
return sandboxContext?.clearModuleContext(target)
}

export function deleteAppClientCache() {
return requireCacheHotReloader?.deleteAppClientCache()
}

export function deleteCache(filePaths: string[]) {
for (const filePath of filePaths) {
requireCacheHotReloader?.deleteCache(filePath)
}
}

export async function getServerField(
dir: string,
field: PropagateToWorkersField
Expand Down
2 changes: 0 additions & 2 deletions packages/next/src/server/lib/router-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ const isNextFont = (pathname: string | null) =>
export type RenderServer = Pick<
typeof import('./render-server'),
| 'initialize'
| 'deleteCache'
| 'clearModuleContext'
| 'deleteAppClientCache'
| 'propagateServerField'
| 'getServerField'
>
Expand Down