diff --git a/crates/next-core/src/next_edge/unsupported.rs b/crates/next-core/src/next_edge/unsupported.rs index d67e571684a4..b3f803e126be 100644 --- a/crates/next-core/src/next_edge/unsupported.rs +++ b/crates/next-core/src/next_edge/unsupported.rs @@ -1,9 +1,11 @@ use anyhow::Result; use indoc::formatdoc; +use turbo_rcstr::RcStr; use turbo_tasks::{ResolvedVc, Vc}; use turbo_tasks_fs::{File, FileSystemPath}; use turbopack_core::{ asset::AssetContent, + ident::AssetIdent, resolve::{ options::{ImportMapResult, ImportMappingReplacement, ReplacedImportMapping}, parse::Request, @@ -13,7 +15,6 @@ use turbopack_core::{ virtual_source::VirtualSource, }; use turbopack_ecmascript::runtime_functions::TURBOPACK_EXPORT_NAMESPACE; -use turbopack_node::execution_context::ExecutionContext; /// Intercepts requests for the given request to `unsupported` error messages /// by returning a VirtualSource proxies to any import request to raise a @@ -21,22 +22,13 @@ use turbopack_node::execution_context::ExecutionContext; /// /// This can be used by import map alias, refer `next_import_map` for the setup. #[turbo_tasks::value(shared)] -pub struct NextEdgeUnsupportedModuleReplacer { - project_path: ResolvedVc, - execution_context: ResolvedVc, -} +pub struct NextEdgeUnsupportedModuleReplacer {} #[turbo_tasks::value_impl] impl NextEdgeUnsupportedModuleReplacer { #[turbo_tasks::function] - pub fn new( - project_path: ResolvedVc, - execution_context: ResolvedVc, - ) -> Vc { - Self::cell(NextEdgeUnsupportedModuleReplacer { - project_path, - execution_context, - }) + pub fn new() -> Vc { + NextEdgeUnsupportedModuleReplacer {}.cell() } } @@ -50,25 +42,37 @@ impl ImportMappingReplacement for NextEdgeUnsupportedModuleReplacer { #[turbo_tasks::function] async fn result( &self, - root_path: Vc, + lookup_path: Vc, request: Vc, ) -> Result> { let request = &*request.await?; if let Request::Module { module, .. } = request { - // packages/next/src/server/web/globals.ts augments global with - // `__import_unsupported` and necessary functions. - let code = formatdoc! { - r#" - {TURBOPACK_EXPORT_NAMESPACE}(__import_unsupported(`{module}`)); - "# - }; - let content = AssetContent::file(File::from(code).into()); - let source = VirtualSource::new(root_path, content).to_resolved().await?; - return Ok( - ImportMapResult::Result(ResolveResult::source(ResolvedVc::upcast(source))).cell(), - ); - }; - - Ok(ImportMapResult::NoEntry.cell()) + // Call out to separate `unsupported_module_source` to only have a single Source cell + // for requests with different subpaths: `fs` and `fs/promises`. + let source = unsupported_module_source(lookup_path.root(), module.clone()) + .to_resolved() + .await?; + Ok(ImportMapResult::Result(ResolveResult::source(ResolvedVc::upcast(source))).cell()) + } else { + Ok(ImportMapResult::NoEntry.cell()) + } } } + +#[turbo_tasks::function] +fn unsupported_module_source(root_path: Vc, module: RcStr) -> Vc { + // packages/next/src/server/web/globals.ts augments global with + // `__import_unsupported` and necessary functions. + let code = formatdoc! { + r#" + {TURBOPACK_EXPORT_NAMESPACE}(__import_unsupported(`{module}`)); + "# + }; + let content = AssetContent::file(File::from(code).into()); + VirtualSource::new_with_ident( + AssetIdent::from_path(root_path).with_modifier(Vc::cell( + format!("unsupported edge import {}", module).into(), + )), + content, + ) +} diff --git a/crates/next-core/src/next_import_map.rs b/crates/next-core/src/next_import_map.rs index b1dd5fef5211..cf9bc88bcaad 100644 --- a/crates/next-core/src/next_import_map.rs +++ b/crates/next-core/src/next_import_map.rs @@ -485,12 +485,7 @@ pub async fn get_next_edge_import_map( | ServerContextType::Pages { .. } | ServerContextType::PagesData { .. } | ServerContextType::PagesApi { .. } => { - insert_unsupported_node_internal_aliases( - &mut import_map, - *project_path, - execution_context, - ) - .await?; + insert_unsupported_node_internal_aliases(&mut import_map).await?; } } @@ -500,13 +495,9 @@ pub async fn get_next_edge_import_map( /// Insert default aliases for the node.js's internal to raise unsupported /// runtime errors. User may provide polyfills for their own by setting user /// config's alias. -async fn insert_unsupported_node_internal_aliases( - import_map: &mut ImportMap, - project_path: Vc, - execution_context: Vc, -) -> Result<()> { +async fn insert_unsupported_node_internal_aliases(import_map: &mut ImportMap) -> Result<()> { let unsupported_replacer = ImportMapping::Dynamic(ResolvedVc::upcast( - NextEdgeUnsupportedModuleReplacer::new(project_path, execution_context) + NextEdgeUnsupportedModuleReplacer::new() .to_resolved() .await?, ))