@@ -4,6 +4,7 @@ use std::{
44 sync:: { Arc , OnceLock } ,
55} ;
66
7+ use regex:: Regex ;
78use rspack_core:: {
89 BoxModule , Compilation , CompilationAsset , CompilationProcessAssets , CompilerThisCompilation ,
910 Context , DependenciesBlock , DependencyCategory , DependencyType , Module , ModuleFactoryCreateData ,
@@ -73,54 +74,56 @@ impl CollectSharedEntryPlugin {
7374 /// Example: ../../../.eden-mono/temp/node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/index.js
7475 /// It locates react-dom's package.json and reads the version field
7576 async fn infer_version ( & self , request : & str ) -> Option < String > {
76- // Convert request string to Path
77- let path = Path :: new ( request) ;
77+ // 1) Try pnpm store path pattern: .pnpm/<pkg>@<version>_
78+ let pnpm_re = Regex :: new ( r"/\\.pnpm/[^/]*@([^/_]+)" ) . ok ( ) ;
79+ if let Some ( re) = pnpm_re {
80+ if let Some ( caps) = re. captures ( request) {
81+ if let Some ( m) = caps. get ( 1 ) {
82+ return Some ( m. as_str ( ) . to_string ( ) ) ;
83+ }
84+ }
85+ }
7886
79- // Find the node_modules segment
80- let mut node_modules_found = false ;
81- let mut package_path = None ;
87+ // 2) Fallback: walk to node_modules/<pkg>[/...] and read package.json
88+ let path = Path :: new ( request) ;
89+ let mut package_json_path = PathBuf :: new ( ) ;
90+ let mut found_node_modules = false ;
91+ let mut need_two_segments = false ;
92+ let mut captured = false ;
8293
8394 for component in path. components ( ) {
8495 let comp_str = component. as_os_str ( ) . to_string_lossy ( ) ;
85- if comp_str == "node_modules" {
86- node_modules_found = true ;
96+ package_json_path. push ( comp_str. as_ref ( ) ) ;
97+ if !found_node_modules && comp_str == "node_modules" {
98+ found_node_modules = true ;
8799 continue ;
88100 }
89-
90- if node_modules_found {
91- // The next component should be the package name
92- package_path = Some ( comp_str. to_string ( ) ) ;
93- break ;
94- }
95- }
96-
97- if let Some ( package_name) = package_path {
98- // Build the full path to package.json
99- let mut package_json_path = PathBuf :: new ( ) ;
100- let mut found_node_modules = false ;
101-
102- for component in path. components ( ) {
103- let comp_str = component. as_os_str ( ) . to_string_lossy ( ) ;
104- package_json_path. push ( comp_str. as_ref ( ) ) ;
105-
106- if comp_str == "node_modules" {
107- found_node_modules = true ;
108- // Append package name directory
109- package_json_path. push ( & package_name) ;
110- // Append package.json
111- package_json_path. push ( "package.json" ) ;
112- break ;
101+ if found_node_modules && !captured {
102+ if comp_str. starts_with ( '@' ) {
103+ // scoped package: need scope + name
104+ need_two_segments = true ;
105+ continue ;
106+ } else {
107+ if need_two_segments {
108+ // this is the name after scope
109+ package_json_path. push ( "package.json" ) ;
110+ captured = true ;
111+ break ;
112+ } else {
113+ // unscoped package name is this segment
114+ package_json_path. push ( "package.json" ) ;
115+ captured = true ;
116+ break ;
117+ }
113118 }
114119 }
120+ }
115121
116- if found_node_modules && package_json_path. exists ( ) {
117- // Try reading package.json
118- if let Ok ( content) = std:: fs:: read_to_string ( & package_json_path) {
119- if let Ok ( json) = serde_json:: from_str :: < serde_json:: Value > ( & content) {
120- // Read the version field
121- if let Some ( version) = json. get ( "version" ) . and_then ( |v| v. as_str ( ) ) {
122- return Some ( version. to_string ( ) ) ;
123- }
122+ if captured && package_json_path. exists ( ) {
123+ if let Ok ( content) = std:: fs:: read_to_string ( & package_json_path) {
124+ if let Ok ( json) = serde_json:: from_str :: < serde_json:: Value > ( & content) {
125+ if let Some ( version) = json. get ( "version" ) . and_then ( |v| v. as_str ( ) ) {
126+ return Some ( version. to_string ( ) ) ;
124127 }
125128 }
126129 }
@@ -346,8 +349,8 @@ async fn process_assets(&self, compilation: &mut Compilation) -> Result<()> {
346349 let mut reqs = ordered_requests. remove ( & key) . unwrap_or_default ( ) ;
347350 for target_id in target_modules {
348351 if let Some ( target) = module_graph. module_by_identifier ( & target_id) {
349- if let Some ( normal ) = target. as_any ( ) . downcast_ref :: < rspack_core :: NormalModule > ( ) {
350- let resource = normal . resource_resolved_data ( ) . resource ( ) . to_string ( ) ;
352+ if let Some ( name ) = target. name_for_condition ( ) {
353+ let resource: String = name . into ( ) ;
351354 let version = self
352355 . infer_version ( & resource)
353356 . await
0 commit comments