diff --git a/packages/next-swc/crates/next-core/src/middleware.rs b/packages/next-swc/crates/next-core/src/middleware.rs index d05a30bd847a..13ec57a4af39 100644 --- a/packages/next-swc/crates/next-core/src/middleware.rs +++ b/packages/next-swc/crates/next-core/src/middleware.rs @@ -29,7 +29,7 @@ pub async fn get_middleware_module( project_root: Vc, userland_module: Vc>, ) -> Result>> { - let template_file = "build/templates/middleware.js"; + let template_file = "middleware.js"; // Load the file from the next.js codebase. let file = load_next_js_template(project_root, template_file.to_string()).await?; diff --git a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs index e41c15bd1169..a20c5f84f3db 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs @@ -70,7 +70,7 @@ pub async fn get_app_page_entry( let original_name = page.to_string(); let pathname = AppPath::from(page.clone()).to_string(); - let template_file = "build/templates/app-page.js"; + let template_file = "app-page.js"; // Load the file from the next.js codebase. let file = load_next_js_template(project_root, template_file.to_string()).await?; diff --git a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs index 838d92dc9003..ab7d381f1f87 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs @@ -56,7 +56,7 @@ pub async fn get_app_route_entry( let path = source.ident().path(); - let template_file = "build/templates/app-route.js"; + let template_file = "app-route.js"; // Load the file from the next.js codebase. let file = load_next_js_template(project_root, template_file.to_string()).await?; diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index d1ec351c0e29..b7f188d42856 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -159,7 +159,7 @@ pub async fn get_client_resolve_options_context( enable_typescript: true, enable_react: true, rules: vec![( - foreign_code_context_condition(next_config).await?, + foreign_code_context_condition(next_config, project_path).await?, module_options_context.clone().cell(), )], ..module_options_context @@ -256,7 +256,7 @@ pub async fn get_client_module_options_context( decorators: Some(decorators_options), rules: vec![ ( - foreign_code_context_condition(next_config).await?, + foreign_code_context_condition(next_config, project_path).await?, module_options_context.clone().cell(), ), // If the module is an internal asset (i.e overlay, fallback) coming from the embedded diff --git a/packages/next-swc/crates/next-core/src/next_edge/context.rs b/packages/next-swc/crates/next-core/src/next_edge/context.rs index 7dc071b1c24e..ee48af025569 100644 --- a/packages/next-swc/crates/next-core/src/next_edge/context.rs +++ b/packages/next-swc/crates/next-core/src/next_edge/context.rs @@ -125,7 +125,7 @@ pub async fn get_edge_resolve_options_context( enable_typescript: true, enable_react: true, rules: vec![( - foreign_code_context_condition(next_config).await?, + foreign_code_context_condition(next_config, project_path).await?, resolve_options_context.clone().cell(), )], ..resolve_options_context diff --git a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs index 7bdbf2d027bb..4dedec9adce4 100644 --- a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs @@ -46,15 +46,15 @@ pub async fn create_page_ssr_entry_module( let template_file = match (&reference_type, runtime) { (ReferenceType::Entry(EntryReferenceSubType::Page), _) => { // Load the Page entry file. - "build/templates/pages.js" + "pages.js" } (ReferenceType::Entry(EntryReferenceSubType::PagesApi), NextRuntime::NodeJs) => { // Load the Pages API entry file. - "build/templates/pages-api.js" + "pages-api.js" } (ReferenceType::Entry(EntryReferenceSubType::PagesApi), NextRuntime::Edge) => { // Load the Pages API entry file. - "build/templates/pages-edge-api.js" + "pages-edge-api.js" } _ => bail!("Invalid path type"), }; diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 7fffe23be44d..1c6418a18831 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -98,7 +98,8 @@ pub async fn get_server_resolve_options_context( ) -> Result> { let next_server_import_map = get_next_server_import_map(project_path, ty, mode, next_config, execution_context); - let foreign_code_context_condition = foreign_code_context_condition(next_config).await?; + let foreign_code_context_condition = + foreign_code_context_condition(next_config, project_path).await?; let root_dir = project_path.root().resolve().await?; let module_feature_report_resolve_plugin = ModuleFeatureReportResolvePlugin::new(project_path); let unsupported_modules_resolve_plugin = UnsupportedModulesResolvePlugin::new(project_path); @@ -215,7 +216,8 @@ pub async fn get_server_module_options_context( let custom_rules = get_next_server_transforms_rules(next_config, ty.into_value(), mode).await?; let internal_custom_rules = get_next_server_internal_transforms_rules(ty.into_value()).await?; - let foreign_code_context_condition = foreign_code_context_condition(next_config).await?; + let foreign_code_context_condition = + foreign_code_context_condition(next_config, project_path).await?; let enable_postcss_transform = Some(PostCssTransformOptions { postcss_package: Some(get_postcss_package_mapping(project_path)), ..Default::default() diff --git a/packages/next-swc/crates/next-core/src/util.rs b/packages/next-swc/crates/next-core/src/util.rs index 78382b8114ed..374d27551f76 100644 --- a/packages/next-swc/crates/next-core/src/util.rs +++ b/packages/next-swc/crates/next-core/src/util.rs @@ -27,6 +27,8 @@ use crate::{ next_import_map::get_next_package, }; +const NEXT_TEMPLATE_PATH: &str = "dist/esm/build/templates"; + #[derive(Debug, Clone, Copy, PartialEq, Eq, TaskInput)] pub enum PathType { PagesPage, @@ -82,13 +84,27 @@ pub fn get_asset_path_from_pathname(pathname: &str, ext: &str) -> String { pub async fn foreign_code_context_condition( next_config: Vc, + project_path: Vc, ) -> Result { let transpile_packages = next_config.transpile_packages().await?; + + // The next template files are allowed to import the user's code via import + // mapping, and imports must use the project-level [ResolveOptions] instead + // of the `node_modules` specific resolve options (the template files are + // technically node module files). + let not_next_template_dir = ContextCondition::not(ContextCondition::InPath( + get_next_package(project_path).join(NEXT_TEMPLATE_PATH.to_string()), + )); + let result = if transpile_packages.is_empty() { - ContextCondition::InDirectory("node_modules".to_string()) + ContextCondition::all(vec![ + ContextCondition::InDirectory("node_modules".to_string()), + not_next_template_dir, + ]) } else { ContextCondition::all(vec![ ContextCondition::InDirectory("node_modules".to_string()), + not_next_template_dir, ContextCondition::not(ContextCondition::any( transpile_packages .iter() @@ -334,11 +350,9 @@ fn parse_config_from_js_value(module: Vc>, value: &JsValue) -> N #[turbo_tasks::function] pub async fn load_next_js_template( project_path: Vc, - path: String, + file: String, ) -> Result> { - let file_path = get_next_package(project_path) - .join("dist/esm".to_string()) - .join(path); + let file_path = virtual_next_js_template_path(project_path, file); let content = &*file_path.read().await?; @@ -352,11 +366,10 @@ pub async fn load_next_js_template( #[turbo_tasks::function] pub fn virtual_next_js_template_path( project_path: Vc, - path: String, + file: String, ) -> Vc { - get_next_package(project_path) - .join("dist/esm".to_string()) - .join(path) + debug_assert!(!file.contains('/')); + get_next_package(project_path).join(format!("{NEXT_TEMPLATE_PATH}/{file}")) } pub async fn load_next_js_templateon(