@@ -21,15 +21,16 @@ use rspack_sources::{
2121 BoxSource , CachedSource , OriginalSource , RawSource , SourceExt , SourceMap , SourceMapSource ,
2222 WithoutOriginalOptions ,
2323} ;
24+ use rustc_hash:: FxHashSet as HashSet ;
2425use rustc_hash:: FxHasher ;
2526use serde_json:: json;
2627
2728use crate :: {
28- contextify, get_context, BoxLoader , BoxModule , BuildContext , BuildInfo , BuildMeta , BuildResult ,
29- CodeGenerationResult , Compilation , CompilerOptions , Context , DependencyTemplate , GenerateContext ,
30- GeneratorOptions , LibIdentOptions , LoaderRunnerPluginProcessResource , Module , ModuleDependency ,
31- ModuleGraph , ModuleIdentifier , ModuleType , ParseContext , ParseResult , ParserAndGenerator ,
32- ParserOptions , Resolve , SourceType ,
29+ add_connection_states , contextify, get_context, BoxLoader , BoxModule , BuildContext , BuildInfo ,
30+ BuildMeta , BuildResult , CodeGenerationResult , Compilation , CompilerOptions , ConnectionState ,
31+ Context , DependencyTemplate , GenerateContext , GeneratorOptions , LibIdentOptions ,
32+ LoaderRunnerPluginProcessResource , Module , ModuleDependency , ModuleGraph , ModuleIdentifier ,
33+ ModuleType , ParseContext , ParseResult , ParserAndGenerator , ParserOptions , Resolve , SourceType ,
3334} ;
3435
3536bitflags ! {
@@ -455,6 +456,40 @@ impl Module for NormalModule {
455456 fn get_context ( & self ) -> Option < & Context > {
456457 Some ( & self . context )
457458 }
459+
460+ // Port from https://github.com/webpack/webpack/blob/main/lib/NormalModule.js#L1120
461+ fn get_side_effects_connection_state (
462+ & self ,
463+ module_graph : & ModuleGraph ,
464+ module_chain : & mut HashSet < ModuleIdentifier > ,
465+ ) -> ConnectionState {
466+ if let Some ( mgm) = module_graph. module_graph_module_by_identifier ( & self . identifier ( ) ) {
467+ if let Some ( side_effect) = mgm. factory_meta . as_ref ( ) . and_then ( |m| m. side_effects ) {
468+ return ConnectionState :: Bool ( side_effect) ;
469+ }
470+ if let Some ( side_effect_free) = mgm. build_meta . as_ref ( ) . and_then ( |m| m. side_effect_free ) && side_effect_free {
471+ // use module chain instead of is_evaluating_side_effects to mut module graph
472+ if module_chain. contains ( & self . identifier ( ) ) {
473+ return ConnectionState :: CircularConnection ;
474+ }
475+ module_chain. insert ( self . identifier ( ) ) ;
476+ let mut current = ConnectionState :: Bool ( false ) ;
477+ for dependency_id in mgm. dependencies . iter ( ) {
478+ if let Some ( dependency) = module_graph. dependency_by_id ( dependency_id) . expect ( "should have dependency" ) . as_module_dependency ( ) {
479+ let state = dependency. get_module_evaluation_side_effects_state ( module_graph, module_chain) ;
480+ if matches ! ( state, ConnectionState :: Bool ( true ) ) {
481+ // TODO add optimization bailout
482+ return ConnectionState :: Bool ( true ) ;
483+ } else if matches ! ( state, ConnectionState :: CircularConnection ) {
484+ current = add_connection_states ( current, state) ;
485+ }
486+ }
487+ }
488+ return current;
489+ }
490+ }
491+ ConnectionState :: Bool ( true )
492+ }
458493}
459494
460495impl PartialEq for NormalModule {
0 commit comments