Skip to content

[turbopack] Stop exposing globals from Turbopack runtime #81727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2025
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
14 changes: 14 additions & 0 deletions packages/next/src/server/app-render/entry-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ if (process.env.NODE_ENV === 'development') {
SegmentViewStateNode = mod.SegmentViewStateNode
}

// For hot-reloader
declare global {
var __next__clear_chunk_cache__: (() => void) | null | undefined
var __turbopack_clear_chunk_cache__: () => void | null | undefined
}
// hot-reloader modules are not bundled so we need to inject `__next__clear_chunk_cache__`
// into globalThis from this file which is bundled.
if (process.env.TURBOPACK) {
globalThis.__next__clear_chunk_cache__ = __turbopack_clear_chunk_cache__
} else {
// Webpack does not have chunks on the server
globalThis.__next__clear_chunk_cache__ = null
}

// patchFetch makes use of APIs such as `React.unstable_postpone` which are only available
// in the experimental channel of React, so export it from here so that it comes from the bundled runtime
export function patchFetch() {
Expand Down
11 changes: 7 additions & 4 deletions packages/next/src/server/dev/hot-reloader-turbopack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ const isTestMode = !!(

const sessionId = Math.floor(Number.MAX_SAFE_INTEGER * Math.random())

declare const __next__clear_chunk_cache__: (() => void) | null | undefined

/**
* Replaces turbopack:///[project] with the specified project in the `source` field.
*/
Expand Down Expand Up @@ -342,10 +344,11 @@ export async function createHotReloaderTurbopack(

resetFetch()

// Edge uses the browser runtime which already disposes chunks individually.
// TODO: process.env.NEXT_RUNTIME is 'nodejs' even though Node.js runtime is not used.
if ('__turbopack_clear_chunk_cache__' in globalThis) {
;(globalThis as any).__turbopack_clear_chunk_cache__()
// Not available in:
// - Pages Router (no server-side HMR)
// - Edge Runtime (uses browser runtime which already disposes chunks individually)
if (typeof __next__clear_chunk_cache__ === 'function') {
__next__clear_chunk_cache__()
}

const serverPaths = writtenEndpoint.serverPaths.map(({ path: p }) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ function instantiateModule(moduleId: ModuleId, source: SourceInfo): Module {
n: exportNamespace.bind(null, module, devModuleCache),
m: module,
c: devModuleCache,
C: null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we probably want to implement that for the browser runtime too, but that could be done later...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. The factoring is still weird because the browser runtime has its own mechanism and doesn't even use clearChunkCache.

M: moduleFactories,
l: loadChunk.bind(null, sourceInfo),
L: loadChunkByUrl.bind(null, sourceInfo),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ function instantiateModule(id: ModuleId, source: SourceInfo): Module {
type: SourceType.Parent,
parentId: id,
}),
C: clearChunkCache,
w: loadWebAssembly,
u: loadWebAssemblyModule,
P: resolveAbsolutePath,
Expand Down Expand Up @@ -381,9 +382,6 @@ function isJs(chunkUrlOrPath: ChunkUrl | ChunkPath): boolean {
return regexJsUrl.test(chunkUrlOrPath)
}

// For hot-reloader
;(globalThis as any).__turbopack_clear_chunk_cache__ = clearChunkCache

module.exports = {
getOrInstantiateRuntimeModule,
loadChunk,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pub const TURBOPACK_LOAD: &TurbopackRuntimeFunctionShortcut =
&TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.l", "l");
pub const TURBOPACK_LOAD_BY_URL: &TurbopackRuntimeFunctionShortcut =
&TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.L", "L");
pub const TURBOPACK_CLEAR_CHUNK_CACHE: &TurbopackRuntimeFunctionShortcut =
&TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.C", "C");
pub const TURBOPACK_DYNAMIC: &TurbopackRuntimeFunctionShortcut =
&TurbopackRuntimeFunctionShortcut::new("__turbopack_context__.j", "j");
pub const TURBOPACK_RESOLVE_ABSOLUTE_PATH: &TurbopackRuntimeFunctionShortcut =
Expand All @@ -81,7 +83,7 @@ pub const TURBOPACK_REQUIRE_REAL: &TurbopackRuntimeFunctionShortcut =

/// Adding an entry to this list will automatically ensure that `__turbopack_XXX__` can be called
/// from user code (by inserting a replacement into free_var_references)
pub const TURBOPACK_RUNTIME_FUNCTION_SHORTCUTS: [(&str, &TurbopackRuntimeFunctionShortcut); 21] = [
pub const TURBOPACK_RUNTIME_FUNCTION_SHORTCUTS: [(&str, &TurbopackRuntimeFunctionShortcut); 22] = [
("__turbopack_require__", TURBOPACK_REQUIRE),
("__turbopack_module_context__", TURBOPACK_MODULE_CONTEXT),
("__turbopack_import__", TURBOPACK_IMPORT),
Expand Down Expand Up @@ -109,4 +111,8 @@ pub const TURBOPACK_RUNTIME_FUNCTION_SHORTCUTS: [(&str, &TurbopackRuntimeFunctio
("__turbopack_refresh__", TURBOPACK_REFRESH),
("__turbopack_require_stub__", TURBOPACK_REQUIRE_STUB),
("__turbopack_require_real__", TURBOPACK_REQUIRE_REAL),
(
"__turbopack_clear_chunk_cache__",
TURBOPACK_CLEAR_CHUNK_CACHE,
),
];

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Loading