@@ -8,8 +8,9 @@ use camino::Utf8Path;
88use regex:: Regex ;
99use rspack_core:: {
1010 BoxModule , Compilation , CompilationAsset , CompilationProcessAssets , CompilerCompilation ,
11- CompilerThisCompilation , Context , DependencyCategory , DependencyType , ModuleFactoryCreateData ,
12- NormalModuleFactoryFactorize , Plugin , ResolveOptionsWithDependencyType , ResolveResult , Resolver ,
11+ CompilerThisCompilation , Context , DependenciesBlock , DependencyCategory , DependencyType , Module ,
12+ ModuleFactoryCreateData , NormalModuleFactoryFactorize , Plugin , ResolveOptionsWithDependencyType ,
13+ ResolveResult , Resolver ,
1314 rspack_sources:: { RawStringSource , SourceExt } ,
1415} ;
1516use rspack_error:: { Diagnostic , Result , error} ;
@@ -322,37 +323,102 @@ async fn this_compilation(
322323
323324#[ plugin_hook( CompilationProcessAssets for CollectShareEntryPlugin ) ]
324325async fn process_assets ( & self , compilation : & mut Compilation ) -> Result < ( ) > {
325- let entries = self . resolved_entries . read ( ) . await ;
326+ dbg ! ( "process_assets" ) ;
327+ // 遍历图中的 ConsumeSharedModule,收集其 fallback 映射到的真实模块地址
328+ let module_graph = compilation. get_module_graph ( ) ;
329+ let mut ordered_requests: FxHashMap < String , Vec < [ String ; 2 ] > > = FxHashMap :: default ( ) ;
330+ let mut share_scopes: FxHashMap < String , String > = FxHashMap :: default ( ) ;
331+
332+ for ( id, module) in module_graph. modules ( ) . into_iter ( ) {
333+ let module_type = module. module_type ( ) ;
334+ dbg ! ( & module_type) ;
335+ if !matches ! ( module_type, rspack_core:: ModuleType :: ConsumeShared ) {
336+ continue ;
337+ }
326338
327- let mut shared: FxHashMap < & str , CollectShareEntryAssetItem < ' _ > > = FxHashMap :: default ( ) ;
328- let mut ordered_requests: FxHashMap < & str , Vec < [ String ; 2 ] > > = FxHashMap :: default ( ) ;
339+ if let Some ( consume) = module
340+ . as_any ( )
341+ . downcast_ref :: < super :: consume_shared_module:: ConsumeSharedModule > ( )
342+ {
343+ // 从 readable_identifier 中解析 share_scope 与 share_key
344+ let ident = consume. readable_identifier ( & Context :: default ( ) ) . to_string ( ) ;
345+ dbg ! ( & ident) ;
346+ // 形如: "consume shared module ({scope}) {share_key}@..."
347+ let ( scope, key) = {
348+ let mut scope = String :: new ( ) ;
349+ let mut key = String :: new ( ) ;
350+ if let Some ( start) = ident. find ( "(" )
351+ && let Some ( end) = ident. find ( ")" )
352+ && end > start
353+ {
354+ scope = ident[ start + 1 ..end] . to_string ( ) ;
355+ }
356+ if let Some ( pos) = ident. find ( ") " ) {
357+ let rest = & ident[ pos + 2 ..] ;
358+ let at = rest. find ( '@' ) . unwrap_or ( rest. len ( ) ) ;
359+ key = rest[ ..at] . to_string ( ) ;
360+ }
361+ ( scope, key)
362+ } ;
329363
330- for ( share_key, record) in entries. iter ( ) {
331- if record. requests . is_empty ( ) {
332- continue ;
364+ if key. is_empty ( ) {
365+ continue ;
366+ }
367+
368+ // 收集该 consume 模块的依赖与异步块中的依赖对应的真实模块
369+ let mut target_modules = Vec :: new ( ) ;
370+ for dep_id in consume. get_dependencies ( ) {
371+ if let Some ( target_id) = module_graph. module_identifier_by_dependency_id ( dep_id) {
372+ target_modules. push ( * target_id) ;
373+ }
374+ }
375+ for block_id in consume. get_blocks ( ) {
376+ if let Some ( block) = module_graph. block_by_id ( block_id) {
377+ for dep_id in block. get_dependencies ( ) {
378+ if let Some ( target_id) = module_graph. module_identifier_by_dependency_id ( dep_id) {
379+ target_modules. push ( * target_id) ;
380+ }
381+ }
382+ }
383+ }
384+
385+ // 将真实模块的资源路径加入到映射集合,并推断版本
386+ let mut reqs = ordered_requests. remove ( & key) . unwrap_or_default ( ) ;
387+ for target_id in target_modules {
388+ if let Some ( target) = module_graph. module_by_identifier ( & target_id) {
389+ if let Some ( normal) = target. as_any ( ) . downcast_ref :: < rspack_core:: NormalModule > ( ) {
390+ let resource = normal. resource_resolved_data ( ) . resource ( ) . to_string ( ) ;
391+ let version = self
392+ . infer_version ( & resource)
393+ . await
394+ . unwrap_or_else ( || "" . to_string ( ) ) ;
395+ let pair = [ resource, version] ;
396+ if !reqs. iter ( ) . any ( |p| p[ 0 ] == pair[ 0 ] && p[ 1 ] == pair[ 1 ] ) {
397+ reqs. push ( pair) ;
398+ }
399+ }
400+ }
401+ }
402+ reqs. sort_by ( |a, b| a[ 0 ] . cmp ( & b[ 0 ] ) . then ( a[ 1 ] . cmp ( & b[ 1 ] ) ) ) ;
403+ ordered_requests. insert ( key. clone ( ) , reqs) ;
404+ if !scope. is_empty ( ) {
405+ share_scopes. insert ( key. clone ( ) , scope) ;
406+ }
333407 }
334- let mut requests: Vec < [ String ; 2 ] > = record
335- . requests
336- . iter ( )
337- . map ( |item| [ item. request . clone ( ) , item. version . clone ( ) ] )
338- . collect ( ) ;
339- requests. sort_by ( |a, b| a[ 0 ] . cmp ( & b[ 0 ] ) . then ( a[ 1 ] . cmp ( & b[ 1 ] ) ) ) ;
340- ordered_requests. insert ( share_key. as_str ( ) , requests) ;
341408 }
342409
343- for ( share_key, record) in entries. iter ( ) {
344- if record. requests . is_empty ( ) {
345- continue ;
346- }
347- let requests = ordered_requests
348- . get ( share_key. as_str ( ) )
349- . map ( |v| v. as_slice ( ) )
350- . unwrap_or ( & [ ] ) ;
410+ // 生成资产内容
411+ let mut shared: FxHashMap < & str , CollectShareEntryAssetItem < ' _ > > = FxHashMap :: default ( ) ;
412+ for ( share_key, requests) in ordered_requests. iter ( ) {
413+ let scope = share_scopes
414+ . get ( share_key)
415+ . map ( |s| s. as_str ( ) )
416+ . unwrap_or ( "" ) ;
351417 shared. insert (
352418 share_key. as_str ( ) ,
353419 CollectShareEntryAssetItem {
354- share_scope : record . share_scope . as_str ( ) ,
355- requests,
420+ share_scope : scope ,
421+ requests : requests . as_slice ( ) ,
356422 } ,
357423 ) ;
358424 }
0 commit comments