From 79201ec1aab266fd515045d9add612b11925dfff Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Thu, 26 Jun 2025 11:34:08 +0200 Subject: [PATCH 1/3] Turbopack: exclude resolve-rewrites if possible --- crates/napi/src/next_api/project.rs | 4 ++++ crates/next-api/benches/hmr.rs | 1 + crates/next-api/src/app.rs | 6 ++++++ crates/next-api/src/pages.rs | 4 ++++ crates/next-api/src/project.rs | 16 ++++++++++++++++ crates/next-build-test/src/main.rs | 1 + crates/next-core/src/next_client/context.rs | 6 ++++++ crates/next-core/src/next_edge/context.rs | 2 ++ crates/next-core/src/next_import_map.rs | 16 ++++++++++++++++ .../next/src/build/swc/generated-native.d.ts | 2 ++ packages/next/src/build/swc/types.ts | 5 +++++ packages/next/src/build/turbopack-build/impl.ts | 1 + .../src/server/dev/hot-reloader-turbopack.ts | 1 + packages/next/src/shared/lib/router/router.ts | 4 +++- packages/next/tsconfig.json | 5 ++++- test/development/basic/next-rs-api.test.ts | 1 + 16 files changed, 73 insertions(+), 2 deletions(-) diff --git a/crates/napi/src/next_api/project.rs b/crates/napi/src/next_api/project.rs index 8d2eef2179fa1b..f378af30dbc173 100644 --- a/crates/napi/src/next_api/project.rs +++ b/crates/napi/src/next_api/project.rs @@ -160,6 +160,9 @@ pub struct NapiProjectOptions { /// The browserslist query to use for targeting browsers. pub browserslist_query: RcStr, + /// Whether there are any rewrites defined + pub has_rewrites: bool, + /// When the code is minified, this opts out of the default mangling of /// local names for variables, functions etc., which can be useful for /// debugging/profiling purposes. @@ -271,6 +274,7 @@ impl From for ProjectOptions { build_id: val.build_id, preview_props: val.preview_props.into(), browserslist_query: val.browserslist_query, + has_rewrites: val.has_rewrites, no_mangling: val.no_mangling, current_node_js_version: val.current_node_js_version, } diff --git a/crates/next-api/benches/hmr.rs b/crates/next-api/benches/hmr.rs index eb6b4cb6ce9436..eb449fa0e76e88 100644 --- a/crates/next-api/benches/hmr.rs +++ b/crates/next-api/benches/hmr.rs @@ -200,6 +200,7 @@ impl HmrBenchmark { preview_mode_signing_key: RcStr::from("test-key"), }, browserslist_query: RcStr::from("last 2 versions"), + has_rewrites: false, no_mangling: false, current_node_js_version: RcStr::from("18.0.0"), }; diff --git a/crates/next-api/src/app.rs b/crates/next-api/src/app.rs index 5c01b67c5e5265..ad5f904e5b1b63 100644 --- a/crates/next-api/src/app.rs +++ b/crates/next-api/src/app.rs @@ -210,6 +210,7 @@ impl AppProject { self.client_ty().owned().await?, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().encryption_key(), self.project().no_mangling(), )) @@ -222,6 +223,7 @@ impl AppProject { self.client_ty().owned().await?, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), )) } @@ -306,6 +308,7 @@ impl AppProject { self.rsc_ty().owned().await?, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), )) } @@ -330,6 +333,7 @@ impl AppProject { self.route_ty().owned().await?, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), )) } @@ -638,6 +642,7 @@ impl AppProject { self.ssr_ty().owned().await?, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), )) } @@ -802,6 +807,7 @@ impl AppProject { self.client_ty().owned().await?, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), ) .resolve_entries(Vc::upcast(self.client_module_context()))) diff --git a/crates/next-api/src/pages.rs b/crates/next-api/src/pages.rs index 6daa0dd48b5ed5..f0c43abc25d377 100644 --- a/crates/next-api/src/pages.rs +++ b/crates/next-api/src/pages.rs @@ -341,6 +341,7 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().encryption_key(), self.project().no_mangling(), )) @@ -355,6 +356,7 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), )) } @@ -564,6 +566,7 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), )) } @@ -577,6 +580,7 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), + self.project().has_rewrites(), self.project().execution_context(), ); Ok(client_runtime_entries.resolve_entries(Vc::upcast(self.client_module_context()))) diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs index 34abe45520332a..eb5ee6584a1b52 100644 --- a/crates/next-api/src/project.rs +++ b/crates/next-api/src/project.rs @@ -183,6 +183,9 @@ pub struct ProjectOptions { /// The browserslist query to use for targeting browsers. pub browserslist_query: RcStr, + /// Whether there are any rewrites defined + pub has_rewrites: bool, + /// When the code is minified, this opts out of the default mangling of /// local names for variables, functions etc., which can be useful for /// debugging/profiling purposes. @@ -447,6 +450,7 @@ impl ProjectContainer { let browserslist_query; let no_mangling; let current_node_js_version; + let has_rewrites; { let options = self.options_state.get(); let options = options @@ -471,6 +475,7 @@ impl ProjectContainer { browserslist_query = options.browserslist_query.clone(); no_mangling = options.no_mangling; current_node_js_version = options.current_node_js_version.clone(); + has_rewrites = options.has_rewrites; } let dist_dir = next_config @@ -489,6 +494,7 @@ impl ProjectContainer { env: ResolvedVc::upcast(env_map.to_resolved().await?), define_env: define_env.to_resolved().await?, browserslist_query, + has_rewrites, mode: if dev { NextMode::Development.resolved_cell() } else { @@ -563,6 +569,9 @@ pub struct Project { /// The browserslist query to use for targeting browsers. browserslist_query: RcStr, + /// Whether there are any rewrites defined + has_rewrites: bool, + mode: ResolvedVc, versioned_content_map: Option>, @@ -766,6 +775,11 @@ impl Project { *self.mode } + #[turbo_tasks::function] + pub(super) fn has_rewrites(&self) -> Vc { + Vc::cell(self.has_rewrites) + } + #[turbo_tasks::function] pub(super) fn is_watch_enabled(&self) -> Result> { Ok(Vc::cell(self.watch.enable)) @@ -1343,6 +1357,7 @@ impl Project { }, self.next_mode(), self.next_config(), + self.has_rewrites(), self.execution_context(), ), Layer::new_with_user_friendly_name( @@ -1573,6 +1588,7 @@ impl Project { }, self.next_mode(), self.next_config(), + self.has_rewrites(), self.execution_context(), ), Layer::new_with_user_friendly_name( diff --git a/crates/next-build-test/src/main.rs b/crates/next-build-test/src/main.rs index 66551611c0182e..ae89477fa48a41 100644 --- a/crates/next-build-test/src/main.rs +++ b/crates/next-build-test/src/main.rs @@ -165,6 +165,7 @@ fn main() { browserslist_query: "last 1 Chrome versions, last 1 Firefox versions, last 1 \ Safari versions, last 1 Edge versions" .into(), + has_rewrites: false, no_mangling: false, current_node_js_version: "18.0.0".into(), }; diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index 8a0a0ecfceb3ec..543a278371aa4f 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -127,6 +127,7 @@ pub async fn get_client_resolve_options_context( ty: ClientContextType, mode: Vc, next_config: Vc, + has_rewrites: Vc, execution_context: Vc, ) -> Result> { let next_client_import_map = get_next_client_import_map( @@ -134,6 +135,7 @@ pub async fn get_client_resolve_options_context( ty.clone(), next_config, mode, + has_rewrites, execution_context, ) .to_resolved() @@ -207,6 +209,7 @@ pub async fn get_client_module_options_context( ty: ClientContextType, mode: Vc, next_config: Vc, + has_rewrites: Vc, encryption_key: ResolvedVc, no_mangling: Vc, ) -> Result> { @@ -216,6 +219,7 @@ pub async fn get_client_module_options_context( ty.clone(), mode, next_config, + has_rewrites, *execution_context, ); @@ -483,6 +487,7 @@ pub async fn get_client_runtime_entries( ty: ClientContextType, mode: Vc, next_config: Vc, + has_rewrites: Vc, execution_context: Vc, ) -> Result> { let mut runtime_entries = vec![]; @@ -491,6 +496,7 @@ pub async fn get_client_runtime_entries( ty.clone(), mode, next_config, + has_rewrites, execution_context, ); diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index e8e0ea1bcc4758..d41062fde6fff0 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -81,6 +81,7 @@ pub async fn get_edge_resolve_options_context( ty: ServerContextType, mode: Vc, next_config: Vc, + has_rewrites: Vc, execution_context: Vc, ) -> Result> { let next_edge_import_map = get_next_edge_import_map( @@ -88,6 +89,7 @@ pub async fn get_edge_resolve_options_context( ty.clone(), next_config, mode, + has_rewrites, execution_context, ) .to_resolved() diff --git a/crates/next-core/src/next_import_map.rs b/crates/next-core/src/next_import_map.rs index 01e7a7e25e7bcd..3208b4a4550547 100644 --- a/crates/next-core/src/next_import_map.rs +++ b/crates/next-core/src/next_import_map.rs @@ -94,6 +94,7 @@ pub async fn get_next_client_import_map( ty: ClientContextType, next_config: Vc, next_mode: Vc, + has_rewrites: Vc, execution_context: Vc, ) -> Result> { let mut import_map = ImportMap::empty(); @@ -239,6 +240,13 @@ pub async fn get_next_client_import_map( }, ); + if !*has_rewrites.await? { + import_map.insert_exact_alias( + "next/dist/shared/lib/router/utils/resolve-rewrites", + ImportMapping::Ignore.resolved_cell(), + ); + } + match ty { ClientContextType::Pages { .. } | ClientContextType::App { .. } @@ -393,6 +401,7 @@ pub async fn get_next_edge_import_map( ty: ServerContextType, next_config: Vc, next_mode: Vc, + has_rewrites: Vc, execution_context: Vc, ) -> Result> { let mut import_map = ImportMap::empty(); @@ -489,6 +498,13 @@ pub async fn get_next_edge_import_map( } } + if !*has_rewrites.await? { + import_map.insert_exact_alias( + "next/dist/shared/lib/router/utils/resolve-rewrites", + ImportMapping::Ignore.resolved_cell(), + ); + } + insert_next_server_special_aliases( &mut import_map, project_path.clone(), diff --git a/packages/next/src/build/swc/generated-native.d.ts b/packages/next/src/build/swc/generated-native.d.ts index 8c68589ecef84e..7036a000306a1c 100644 --- a/packages/next/src/build/swc/generated-native.d.ts +++ b/packages/next/src/build/swc/generated-native.d.ts @@ -134,6 +134,8 @@ export interface NapiProjectOptions { previewProps: NapiDraftModeOptions /** The browserslist query to use for targeting browsers. */ browserslistQuery: RcStr + /** Whether there are any rewrites defined */ + hasRewrites: boolean /** * When the code is minified, this opts out of the default mangling of * local names for variables, functions etc., which can be useful for diff --git a/packages/next/src/build/swc/types.ts b/packages/next/src/build/swc/types.ts index 5c3f074d1204d7..910b9c78b9d58e 100644 --- a/packages/next/src/build/swc/types.ts +++ b/packages/next/src/build/swc/types.ts @@ -417,6 +417,11 @@ export interface ProjectOptions { */ browserslistQuery: string + /** + * Whether there are any rewrites defined + */ + hasRewrites: boolean + /** * When the code is minified, this opts out of the default mangling of local * names for variables, functions etc., which can be useful for diff --git a/packages/next/src/build/turbopack-build/impl.ts b/packages/next/src/build/turbopack-build/impl.ts index a9e9673d22b207..d845a6db29ef58 100644 --- a/packages/next/src/build/turbopack-build/impl.ts +++ b/packages/next/src/build/turbopack-build/impl.ts @@ -81,6 +81,7 @@ export async function turbopackBuild(): Promise<{ encryptionKey, previewProps, browserslistQuery: supportedBrowsers.join(', '), + hasRewrites, noMangling, currentNodeJsVersion, }, diff --git a/packages/next/src/server/dev/hot-reloader-turbopack.ts b/packages/next/src/server/dev/hot-reloader-turbopack.ts index dd2ea272507e53..35a7f9eeab9979 100644 --- a/packages/next/src/server/dev/hot-reloader-turbopack.ts +++ b/packages/next/src/server/dev/hot-reloader-turbopack.ts @@ -241,6 +241,7 @@ export async function createHotReloaderTurbopack( encryptionKey, previewProps: opts.fsChecker.prerenderManifest.preview, browserslistQuery: supportedBrowsers.join(', '), + hasRewrites, noMangling: false, currentNodeJsVersion, }, diff --git a/packages/next/src/shared/lib/router/router.ts b/packages/next/src/shared/lib/router/router.ts index 807d91c79fb504..f56dd61fa320a4 100644 --- a/packages/next/src/shared/lib/router/router.ts +++ b/packages/next/src/shared/lib/router/router.ts @@ -22,7 +22,9 @@ import mitt from '../mitt' import { getLocationOrigin, getURL, loadGetInitialProps, ST } from '../utils' import { isDynamicRoute } from './utils/is-dynamic' import { parseRelativeUrl } from './utils/parse-relative-url' -import resolveRewrites from './utils/resolve-rewrites' +// Use the full specifier here, so that this can easily be excluded in Turbopack if there are no rewrites. +// This hack could be removed once we use an ESM build of Next.js and correctly specify sideEffects: false. +import resolveRewrites from 'next/dist/shared/lib/router/utils/resolve-rewrites' import { getRouteMatcher } from './utils/route-matcher' import { getRouteRegex } from './utils/route-regex' import { formatWithValidation } from './utils/format-url' diff --git a/packages/next/tsconfig.json b/packages/next/tsconfig.json index 454c1b70927b79..e3d1228f6e9349 100644 --- a/packages/next/tsconfig.json +++ b/packages/next/tsconfig.json @@ -29,7 +29,10 @@ // "next/dist/compiled/next-devtools": [ // "./src/next-devtools/entrypoint.ts" // ], - "next/dist/shared/lib/image-loader": ["./src/shared/lib/image-loader.ts"] + "next/dist/shared/lib/image-loader": ["./src/shared/lib/image-loader.ts"], + "next/dist/shared/lib/router/utils/resolve-rewrites": [ + "./src/shared/lib/router/utils/resolve-rewrites.ts" + ] } }, // When changing `exclude`, also update diff --git a/test/development/basic/next-rs-api.test.ts b/test/development/basic/next-rs-api.test.ts index 714b8b1cf8c371..32c4248ef7a921 100644 --- a/test/development/basic/next-rs-api.test.ts +++ b/test/development/basic/next-rs-api.test.ts @@ -235,6 +235,7 @@ describe('next.rs api', () => { previewModeSigningKey: '12345', }, browserslistQuery: 'last 2 versions', + hasRewrites: false, noMangling: false, currentNodeJsVersion: '18.0.0', }) From 86fc6afda07578a8522334938779a6945faf7291 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 1 Jul 2025 11:48:11 +0200 Subject: [PATCH 2/3] Revert "Turbopack: exclude resolve-rewrites if possible" This reverts commit cb469a0cae4e089cb6be7c4e07a7ff71e9cc38b6. --- crates/napi/src/next_api/project.rs | 4 ---- crates/next-api/benches/hmr.rs | 1 - crates/next-api/src/app.rs | 6 ------ crates/next-api/src/pages.rs | 4 ---- crates/next-api/src/project.rs | 16 ---------------- crates/next-build-test/src/main.rs | 1 - crates/next-core/src/next_client/context.rs | 6 ------ crates/next-core/src/next_edge/context.rs | 2 -- crates/next-core/src/next_import_map.rs | 16 ---------------- .../next/src/build/swc/generated-native.d.ts | 2 -- packages/next/src/build/swc/types.ts | 5 ----- packages/next/src/build/turbopack-build/impl.ts | 1 - .../src/server/dev/hot-reloader-turbopack.ts | 1 - packages/next/src/shared/lib/router/router.ts | 4 +--- packages/next/tsconfig.json | 5 +---- test/development/basic/next-rs-api.test.ts | 1 - 16 files changed, 2 insertions(+), 73 deletions(-) diff --git a/crates/napi/src/next_api/project.rs b/crates/napi/src/next_api/project.rs index f378af30dbc173..8d2eef2179fa1b 100644 --- a/crates/napi/src/next_api/project.rs +++ b/crates/napi/src/next_api/project.rs @@ -160,9 +160,6 @@ pub struct NapiProjectOptions { /// The browserslist query to use for targeting browsers. pub browserslist_query: RcStr, - /// Whether there are any rewrites defined - pub has_rewrites: bool, - /// When the code is minified, this opts out of the default mangling of /// local names for variables, functions etc., which can be useful for /// debugging/profiling purposes. @@ -274,7 +271,6 @@ impl From for ProjectOptions { build_id: val.build_id, preview_props: val.preview_props.into(), browserslist_query: val.browserslist_query, - has_rewrites: val.has_rewrites, no_mangling: val.no_mangling, current_node_js_version: val.current_node_js_version, } diff --git a/crates/next-api/benches/hmr.rs b/crates/next-api/benches/hmr.rs index eb449fa0e76e88..eb6b4cb6ce9436 100644 --- a/crates/next-api/benches/hmr.rs +++ b/crates/next-api/benches/hmr.rs @@ -200,7 +200,6 @@ impl HmrBenchmark { preview_mode_signing_key: RcStr::from("test-key"), }, browserslist_query: RcStr::from("last 2 versions"), - has_rewrites: false, no_mangling: false, current_node_js_version: RcStr::from("18.0.0"), }; diff --git a/crates/next-api/src/app.rs b/crates/next-api/src/app.rs index ad5f904e5b1b63..5c01b67c5e5265 100644 --- a/crates/next-api/src/app.rs +++ b/crates/next-api/src/app.rs @@ -210,7 +210,6 @@ impl AppProject { self.client_ty().owned().await?, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().encryption_key(), self.project().no_mangling(), )) @@ -223,7 +222,6 @@ impl AppProject { self.client_ty().owned().await?, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), )) } @@ -308,7 +306,6 @@ impl AppProject { self.rsc_ty().owned().await?, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), )) } @@ -333,7 +330,6 @@ impl AppProject { self.route_ty().owned().await?, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), )) } @@ -642,7 +638,6 @@ impl AppProject { self.ssr_ty().owned().await?, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), )) } @@ -807,7 +802,6 @@ impl AppProject { self.client_ty().owned().await?, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), ) .resolve_entries(Vc::upcast(self.client_module_context()))) diff --git a/crates/next-api/src/pages.rs b/crates/next-api/src/pages.rs index f0c43abc25d377..6daa0dd48b5ed5 100644 --- a/crates/next-api/src/pages.rs +++ b/crates/next-api/src/pages.rs @@ -341,7 +341,6 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().encryption_key(), self.project().no_mangling(), )) @@ -356,7 +355,6 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), )) } @@ -566,7 +564,6 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), )) } @@ -580,7 +577,6 @@ impl PagesProject { }, self.project().next_mode(), self.project().next_config(), - self.project().has_rewrites(), self.project().execution_context(), ); Ok(client_runtime_entries.resolve_entries(Vc::upcast(self.client_module_context()))) diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs index eb5ee6584a1b52..34abe45520332a 100644 --- a/crates/next-api/src/project.rs +++ b/crates/next-api/src/project.rs @@ -183,9 +183,6 @@ pub struct ProjectOptions { /// The browserslist query to use for targeting browsers. pub browserslist_query: RcStr, - /// Whether there are any rewrites defined - pub has_rewrites: bool, - /// When the code is minified, this opts out of the default mangling of /// local names for variables, functions etc., which can be useful for /// debugging/profiling purposes. @@ -450,7 +447,6 @@ impl ProjectContainer { let browserslist_query; let no_mangling; let current_node_js_version; - let has_rewrites; { let options = self.options_state.get(); let options = options @@ -475,7 +471,6 @@ impl ProjectContainer { browserslist_query = options.browserslist_query.clone(); no_mangling = options.no_mangling; current_node_js_version = options.current_node_js_version.clone(); - has_rewrites = options.has_rewrites; } let dist_dir = next_config @@ -494,7 +489,6 @@ impl ProjectContainer { env: ResolvedVc::upcast(env_map.to_resolved().await?), define_env: define_env.to_resolved().await?, browserslist_query, - has_rewrites, mode: if dev { NextMode::Development.resolved_cell() } else { @@ -569,9 +563,6 @@ pub struct Project { /// The browserslist query to use for targeting browsers. browserslist_query: RcStr, - /// Whether there are any rewrites defined - has_rewrites: bool, - mode: ResolvedVc, versioned_content_map: Option>, @@ -775,11 +766,6 @@ impl Project { *self.mode } - #[turbo_tasks::function] - pub(super) fn has_rewrites(&self) -> Vc { - Vc::cell(self.has_rewrites) - } - #[turbo_tasks::function] pub(super) fn is_watch_enabled(&self) -> Result> { Ok(Vc::cell(self.watch.enable)) @@ -1357,7 +1343,6 @@ impl Project { }, self.next_mode(), self.next_config(), - self.has_rewrites(), self.execution_context(), ), Layer::new_with_user_friendly_name( @@ -1588,7 +1573,6 @@ impl Project { }, self.next_mode(), self.next_config(), - self.has_rewrites(), self.execution_context(), ), Layer::new_with_user_friendly_name( diff --git a/crates/next-build-test/src/main.rs b/crates/next-build-test/src/main.rs index ae89477fa48a41..66551611c0182e 100644 --- a/crates/next-build-test/src/main.rs +++ b/crates/next-build-test/src/main.rs @@ -165,7 +165,6 @@ fn main() { browserslist_query: "last 1 Chrome versions, last 1 Firefox versions, last 1 \ Safari versions, last 1 Edge versions" .into(), - has_rewrites: false, no_mangling: false, current_node_js_version: "18.0.0".into(), }; diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index 543a278371aa4f..8a0a0ecfceb3ec 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -127,7 +127,6 @@ pub async fn get_client_resolve_options_context( ty: ClientContextType, mode: Vc, next_config: Vc, - has_rewrites: Vc, execution_context: Vc, ) -> Result> { let next_client_import_map = get_next_client_import_map( @@ -135,7 +134,6 @@ pub async fn get_client_resolve_options_context( ty.clone(), next_config, mode, - has_rewrites, execution_context, ) .to_resolved() @@ -209,7 +207,6 @@ pub async fn get_client_module_options_context( ty: ClientContextType, mode: Vc, next_config: Vc, - has_rewrites: Vc, encryption_key: ResolvedVc, no_mangling: Vc, ) -> Result> { @@ -219,7 +216,6 @@ pub async fn get_client_module_options_context( ty.clone(), mode, next_config, - has_rewrites, *execution_context, ); @@ -487,7 +483,6 @@ pub async fn get_client_runtime_entries( ty: ClientContextType, mode: Vc, next_config: Vc, - has_rewrites: Vc, execution_context: Vc, ) -> Result> { let mut runtime_entries = vec![]; @@ -496,7 +491,6 @@ pub async fn get_client_runtime_entries( ty.clone(), mode, next_config, - has_rewrites, execution_context, ); diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index d41062fde6fff0..e8e0ea1bcc4758 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -81,7 +81,6 @@ pub async fn get_edge_resolve_options_context( ty: ServerContextType, mode: Vc, next_config: Vc, - has_rewrites: Vc, execution_context: Vc, ) -> Result> { let next_edge_import_map = get_next_edge_import_map( @@ -89,7 +88,6 @@ pub async fn get_edge_resolve_options_context( ty.clone(), next_config, mode, - has_rewrites, execution_context, ) .to_resolved() diff --git a/crates/next-core/src/next_import_map.rs b/crates/next-core/src/next_import_map.rs index 3208b4a4550547..01e7a7e25e7bcd 100644 --- a/crates/next-core/src/next_import_map.rs +++ b/crates/next-core/src/next_import_map.rs @@ -94,7 +94,6 @@ pub async fn get_next_client_import_map( ty: ClientContextType, next_config: Vc, next_mode: Vc, - has_rewrites: Vc, execution_context: Vc, ) -> Result> { let mut import_map = ImportMap::empty(); @@ -240,13 +239,6 @@ pub async fn get_next_client_import_map( }, ); - if !*has_rewrites.await? { - import_map.insert_exact_alias( - "next/dist/shared/lib/router/utils/resolve-rewrites", - ImportMapping::Ignore.resolved_cell(), - ); - } - match ty { ClientContextType::Pages { .. } | ClientContextType::App { .. } @@ -401,7 +393,6 @@ pub async fn get_next_edge_import_map( ty: ServerContextType, next_config: Vc, next_mode: Vc, - has_rewrites: Vc, execution_context: Vc, ) -> Result> { let mut import_map = ImportMap::empty(); @@ -498,13 +489,6 @@ pub async fn get_next_edge_import_map( } } - if !*has_rewrites.await? { - import_map.insert_exact_alias( - "next/dist/shared/lib/router/utils/resolve-rewrites", - ImportMapping::Ignore.resolved_cell(), - ); - } - insert_next_server_special_aliases( &mut import_map, project_path.clone(), diff --git a/packages/next/src/build/swc/generated-native.d.ts b/packages/next/src/build/swc/generated-native.d.ts index 7036a000306a1c..8c68589ecef84e 100644 --- a/packages/next/src/build/swc/generated-native.d.ts +++ b/packages/next/src/build/swc/generated-native.d.ts @@ -134,8 +134,6 @@ export interface NapiProjectOptions { previewProps: NapiDraftModeOptions /** The browserslist query to use for targeting browsers. */ browserslistQuery: RcStr - /** Whether there are any rewrites defined */ - hasRewrites: boolean /** * When the code is minified, this opts out of the default mangling of * local names for variables, functions etc., which can be useful for diff --git a/packages/next/src/build/swc/types.ts b/packages/next/src/build/swc/types.ts index 910b9c78b9d58e..5c3f074d1204d7 100644 --- a/packages/next/src/build/swc/types.ts +++ b/packages/next/src/build/swc/types.ts @@ -417,11 +417,6 @@ export interface ProjectOptions { */ browserslistQuery: string - /** - * Whether there are any rewrites defined - */ - hasRewrites: boolean - /** * When the code is minified, this opts out of the default mangling of local * names for variables, functions etc., which can be useful for diff --git a/packages/next/src/build/turbopack-build/impl.ts b/packages/next/src/build/turbopack-build/impl.ts index d845a6db29ef58..a9e9673d22b207 100644 --- a/packages/next/src/build/turbopack-build/impl.ts +++ b/packages/next/src/build/turbopack-build/impl.ts @@ -81,7 +81,6 @@ export async function turbopackBuild(): Promise<{ encryptionKey, previewProps, browserslistQuery: supportedBrowsers.join(', '), - hasRewrites, noMangling, currentNodeJsVersion, }, diff --git a/packages/next/src/server/dev/hot-reloader-turbopack.ts b/packages/next/src/server/dev/hot-reloader-turbopack.ts index 35a7f9eeab9979..dd2ea272507e53 100644 --- a/packages/next/src/server/dev/hot-reloader-turbopack.ts +++ b/packages/next/src/server/dev/hot-reloader-turbopack.ts @@ -241,7 +241,6 @@ export async function createHotReloaderTurbopack( encryptionKey, previewProps: opts.fsChecker.prerenderManifest.preview, browserslistQuery: supportedBrowsers.join(', '), - hasRewrites, noMangling: false, currentNodeJsVersion, }, diff --git a/packages/next/src/shared/lib/router/router.ts b/packages/next/src/shared/lib/router/router.ts index f56dd61fa320a4..807d91c79fb504 100644 --- a/packages/next/src/shared/lib/router/router.ts +++ b/packages/next/src/shared/lib/router/router.ts @@ -22,9 +22,7 @@ import mitt from '../mitt' import { getLocationOrigin, getURL, loadGetInitialProps, ST } from '../utils' import { isDynamicRoute } from './utils/is-dynamic' import { parseRelativeUrl } from './utils/parse-relative-url' -// Use the full specifier here, so that this can easily be excluded in Turbopack if there are no rewrites. -// This hack could be removed once we use an ESM build of Next.js and correctly specify sideEffects: false. -import resolveRewrites from 'next/dist/shared/lib/router/utils/resolve-rewrites' +import resolveRewrites from './utils/resolve-rewrites' import { getRouteMatcher } from './utils/route-matcher' import { getRouteRegex } from './utils/route-regex' import { formatWithValidation } from './utils/format-url' diff --git a/packages/next/tsconfig.json b/packages/next/tsconfig.json index e3d1228f6e9349..454c1b70927b79 100644 --- a/packages/next/tsconfig.json +++ b/packages/next/tsconfig.json @@ -29,10 +29,7 @@ // "next/dist/compiled/next-devtools": [ // "./src/next-devtools/entrypoint.ts" // ], - "next/dist/shared/lib/image-loader": ["./src/shared/lib/image-loader.ts"], - "next/dist/shared/lib/router/utils/resolve-rewrites": [ - "./src/shared/lib/router/utils/resolve-rewrites.ts" - ] + "next/dist/shared/lib/image-loader": ["./src/shared/lib/image-loader.ts"] } }, // When changing `exclude`, also update diff --git a/test/development/basic/next-rs-api.test.ts b/test/development/basic/next-rs-api.test.ts index 32c4248ef7a921..714b8b1cf8c371 100644 --- a/test/development/basic/next-rs-api.test.ts +++ b/test/development/basic/next-rs-api.test.ts @@ -235,7 +235,6 @@ describe('next.rs api', () => { previewModeSigningKey: '12345', }, browserslistQuery: 'last 2 versions', - hasRewrites: false, noMangling: false, currentNodeJsVersion: '18.0.0', }) From 468cc7fe68d7d66b7fc76fa246fd31166d2532be Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 27 Jun 2025 12:03:21 +0200 Subject: [PATCH 3/3] Use conditional require instead --- packages/next/src/build/create-compiler-aliases.ts | 14 -------------- packages/next/src/build/webpack-config.ts | 1 - packages/next/src/shared/lib/router/router.ts | 8 +++++++- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/packages/next/src/build/create-compiler-aliases.ts b/packages/next/src/build/create-compiler-aliases.ts index e6ed5c13e89e17..afd8d3e16c6247 100644 --- a/packages/next/src/build/create-compiler-aliases.ts +++ b/packages/next/src/build/create-compiler-aliases.ts @@ -35,7 +35,6 @@ export function createWebpackAliases({ appDir, dir, reactProductionProfiling, - hasRewrites, }: { distDir: string isClient: boolean @@ -46,12 +45,8 @@ export function createWebpackAliases({ appDir: string | undefined dir: string reactProductionProfiling: boolean - hasRewrites: boolean }): CompilerAliases { const pageExtensions = config.pageExtensions - const clientResolveRewrites = require.resolve( - '../shared/lib/router/utils/resolve-rewrites' - ) const customAppAliases: CompilerAliases = {} const customDocumentAliases: CompilerAliases = {} @@ -170,15 +165,6 @@ export function createWebpackAliases({ [RSC_DYNAMIC_IMPORT_WRAPPER_ALIAS]: 'next/dist/build/webpack/loaders/next-flight-loader/track-dynamic-import', - ...(isClient || isEdgeServer - ? { - [clientResolveRewrites]: hasRewrites - ? clientResolveRewrites - : // With webpack 5 an alias can be pointed to false to noop - false, - } - : {}), - '@swc/helpers/_': path.join( path.dirname(require.resolve('@swc/helpers/package.json')), '_' diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 1541165b5ee376..6c2d47c5d0fb06 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -777,7 +777,6 @@ export default async function getBaseWebpackConfig( appDir, dir, reactProductionProfiling, - hasRewrites, }), ...(isClient ? { diff --git a/packages/next/src/shared/lib/router/router.ts b/packages/next/src/shared/lib/router/router.ts index 807d91c79fb504..f799067b709179 100644 --- a/packages/next/src/shared/lib/router/router.ts +++ b/packages/next/src/shared/lib/router/router.ts @@ -22,7 +22,6 @@ import mitt from '../mitt' import { getLocationOrigin, getURL, loadGetInitialProps, ST } from '../utils' import { isDynamicRoute } from './utils/is-dynamic' import { parseRelativeUrl } from './utils/parse-relative-url' -import resolveRewrites from './utils/resolve-rewrites' import { getRouteMatcher } from './utils/route-matcher' import { getRouteRegex } from './utils/route-regex' import { formatWithValidation } from './utils/format-url' @@ -46,6 +45,13 @@ import { handleSmoothScroll } from './utils/handle-smooth-scroll' import type { Params } from '../../../server/request/params' import { MATCHED_PATH_HEADER } from '../../../lib/constants' +let resolveRewrites: typeof import('./utils/resolve-rewrites').default +if (process.env.__NEXT_HAS_REWRITES) { + resolveRewrites = ( + require('./utils/resolve-rewrites') as typeof import('./utils/resolve-rewrites') + ).default +} + declare global { interface Window { /* prod */