@@ -2494,6 +2494,22 @@ impl ModuleGraph {
24942494 self . has_node_specifier = has_node_specifier;
24952495 }
24962496
2497+ /// Removes the npm specifiers from the graph including roots and redirects.
2498+ pub fn remove_npm_specifiers ( & mut self ) {
2499+ self
2500+ . module_slots
2501+ . retain ( |_, slot| !matches ! ( slot, ModuleSlot :: Module ( Module :: Npm ( _) ) ) ) ;
2502+ self . redirects . retain ( |_, to| to. scheme ( ) != "npm" ) ;
2503+ self . roots . retain ( |root| root. scheme ( ) != "npm" ) ;
2504+ let is_npm =
2505+ |s : & Resolution | s. maybe_specifier ( ) . is_some_and ( |s| s. scheme ( ) == "npm" ) ;
2506+ for graph_import in self . imports . values_mut ( ) {
2507+ graph_import
2508+ . dependencies
2509+ . retain ( |_, dep| !is_npm ( & dep. maybe_code ) && !is_npm ( & dep. maybe_type ) ) ;
2510+ }
2511+ }
2512+
24972513 /// Iterates over all the module entries in the module graph searching from the provided roots.
24982514 pub fn walk < ' a , ' options > (
24992515 & ' a self ,
@@ -5202,15 +5218,19 @@ impl<'a, 'graph> Builder<'a, 'graph> {
52025218 options. in_dynamic_branch ,
52035219 ) ;
52045220 } else {
5205- // mark external
5206- self . graph . module_slots . insert (
5207- specifier. clone ( ) ,
5208- ModuleSlot :: Module ( Module :: External ( ExternalModule {
5209- maybe_cache_info : None ,
5210- specifier : specifier. clone ( ) ,
5211- was_asset_load : false ,
5212- } ) ) ,
5213- ) ;
5221+ self . load_pending_module ( PendingModuleLoadItem {
5222+ redirect_count,
5223+ requested_specifier : specifier. clone ( ) ,
5224+ maybe_attribute_type : options. maybe_attribute_type ,
5225+ maybe_range : maybe_range. cloned ( ) ,
5226+ maybe_source_phase_referrer : maybe_source_phase_referrer. cloned ( ) ,
5227+ load_specifier : specifier. clone ( ) ,
5228+ is_asset : options. is_asset ,
5229+ in_dynamic_branch : options. in_dynamic_branch ,
5230+ is_root : options. is_root ,
5231+ maybe_checksum : None ,
5232+ maybe_version_info : None ,
5233+ } ) ;
52145234 }
52155235 }
52165236 Ok ( LoadSpecifierKind :: Node ( module_name) ) => {
@@ -8338,6 +8358,115 @@ mod tests {
83388358 assert_eq ! ( errors. len( ) , 1 ) ;
83398359 }
83408360
8361+ #[ test]
8362+ fn remove_npm_specifiers ( ) {
8363+ let mut graph = ModuleGraph :: new ( GraphKind :: All ) ;
8364+
8365+ let file_specifier = ModuleSpecifier :: parse ( "file:///foo.js" ) . unwrap ( ) ;
8366+ let npm_specifier = ModuleSpecifier :: parse ( "npm:chalk@1.0.0" ) . unwrap ( ) ;
8367+ let npm_redirect_from =
8368+ ModuleSpecifier :: parse ( "file:///node_modules/chalk/index.js" ) . unwrap ( ) ;
8369+
8370+ // add a js module
8371+ graph. module_slots . insert (
8372+ file_specifier. clone ( ) ,
8373+ ModuleSlot :: Module ( Module :: Js ( JsModule {
8374+ specifier : file_specifier. clone ( ) ,
8375+ dependencies : Default :: default ( ) ,
8376+ maybe_types_dependency : None ,
8377+ maybe_cache_info : None ,
8378+ maybe_source_map_dependency : None ,
8379+ source : ModuleTextSource :: new_unknown ( Default :: default ( ) ) ,
8380+ media_type : MediaType :: JavaScript ,
8381+ is_script : false ,
8382+ mtime : None ,
8383+ #[ cfg( feature = "fast_check" ) ]
8384+ fast_check : Default :: default ( ) ,
8385+ } ) ) ,
8386+ ) ;
8387+
8388+ // add an npm module
8389+ graph. module_slots . insert (
8390+ npm_specifier. clone ( ) ,
8391+ ModuleSlot :: Module ( Module :: Npm ( NpmModule {
8392+ specifier : npm_specifier. clone ( ) ,
8393+ pkg_req_ref : deno_semver:: npm:: NpmPackageReqReference :: from_str (
8394+ "npm:chalk@1.0.0" ,
8395+ )
8396+ . unwrap ( ) ,
8397+ } ) ) ,
8398+ ) ;
8399+
8400+ // add a redirect pointing to the npm specifier
8401+ graph
8402+ . redirects
8403+ . insert ( npm_redirect_from. clone ( ) , npm_specifier. clone ( ) ) ;
8404+
8405+ // add npm as a root
8406+ graph. roots . insert ( file_specifier. clone ( ) ) ;
8407+ graph. roots . insert ( npm_specifier. clone ( ) ) ;
8408+
8409+ // add an import with an npm dependency
8410+ let import_referrer = ModuleSpecifier :: parse ( "file:///deno.json" ) . unwrap ( ) ;
8411+ let mut deps = IndexMap :: new ( ) ;
8412+ deps. insert (
8413+ "chalk" . to_string ( ) ,
8414+ Dependency {
8415+ maybe_code : Resolution :: Ok ( Box :: new ( ResolutionResolved {
8416+ specifier : npm_specifier. clone ( ) ,
8417+ range : Range {
8418+ specifier : import_referrer. clone ( ) ,
8419+ range : PositionRange :: zeroed ( ) ,
8420+ resolution_mode : None ,
8421+ } ,
8422+ } ) ) ,
8423+ ..Default :: default ( )
8424+ } ,
8425+ ) ;
8426+ deps. insert (
8427+ "./local.js" . to_string ( ) ,
8428+ Dependency {
8429+ maybe_code : Resolution :: Ok ( Box :: new ( ResolutionResolved {
8430+ specifier : file_specifier. clone ( ) ,
8431+ range : Range {
8432+ specifier : import_referrer. clone ( ) ,
8433+ range : PositionRange :: zeroed ( ) ,
8434+ resolution_mode : None ,
8435+ } ,
8436+ } ) ) ,
8437+ ..Default :: default ( )
8438+ } ,
8439+ ) ;
8440+ graph
8441+ . imports
8442+ . insert ( import_referrer, GraphImport { dependencies : deps } ) ;
8443+
8444+ // verify initial state
8445+ assert_eq ! ( graph. module_slots. len( ) , 2 ) ;
8446+ assert_eq ! ( graph. redirects. len( ) , 1 ) ;
8447+ assert_eq ! ( graph. roots. len( ) , 2 ) ;
8448+ assert_eq ! ( graph. imports[ 0 ] . dependencies. len( ) , 2 ) ;
8449+
8450+ graph. remove_npm_specifiers ( ) ;
8451+
8452+ // npm module slot removed, js module slot kept
8453+ assert_eq ! ( graph. module_slots. len( ) , 1 ) ;
8454+ assert ! ( graph. get( & file_specifier) . is_some( ) ) ;
8455+ assert ! ( graph. get( & npm_specifier) . is_none( ) ) ;
8456+
8457+ // npm redirect removed
8458+ assert_eq ! ( graph. redirects. len( ) , 0 ) ;
8459+
8460+ // npm root removed
8461+ assert_eq ! ( graph. roots. len( ) , 1 ) ;
8462+ assert ! ( graph. roots. contains( & file_specifier) ) ;
8463+
8464+ // npm import dependency removed, local kept
8465+ assert_eq ! ( graph. imports[ 0 ] . dependencies. len( ) , 1 ) ;
8466+ assert ! ( graph. imports[ 0 ] . dependencies. contains_key( "./local.js" ) ) ;
8467+ assert ! ( !graph. imports[ 0 ] . dependencies. contains_key( "chalk" ) ) ;
8468+ }
8469+
83418470 #[ test]
83428471 fn module_text_source_bom ( ) {
83438472 let module_text_source = ModuleTextSource {
0 commit comments