@@ -9,18 +9,16 @@ use rspack_cacheable::{
9
9
cacheable, cacheable_dyn,
10
10
with:: { AsInner , AsMap } ,
11
11
} ;
12
- use rspack_collections:: Identifier ;
13
12
use rspack_core:: {
14
- AssetInfo , BoxDependency , BuildMetaExportsType , ChunkGraph , Compilation ,
15
- DependencyType :: WasmImport ,
16
- ExportsInfoGetter , Filename , GenerateContext , GetUsedNameParam , Module , ModuleDependency ,
17
- ModuleGraph , ModuleId , ModuleIdentifier , NormalModule , ParseContext , ParseResult ,
18
- ParserAndGenerator , PathData , PrefetchExportsInfoMode , RuntimeGlobals , SourceType ,
19
- StaticExportsDependency , StaticExportsSpec , UsedName , property_access,
13
+ AssetInfo , BoxDependency , BuildMetaExportsType , ChunkGraph , CodeGenerationData , Compilation ,
14
+ Dependency , DependencyId , DependencyType , Filename , GenerateContext , Module , ModuleDependency ,
15
+ ModuleGraph , ModuleIdentifier , ModuleInitFragments , NormalModule , ParseContext , ParseResult ,
16
+ ParserAndGenerator , PathData , RuntimeGlobals , SourceType , StaticExportsDependency ,
17
+ StaticExportsSpec , TemplateContext , export_from_import, import_statement,
20
18
rspack_sources:: { BoxSource , RawStringSource , Source , SourceExt } ,
21
19
} ;
22
20
use rspack_error:: { Diagnostic , IntoTWithDiagnosticArray , Result , TWithDiagnosticArray } ;
23
- use rspack_util:: itoa;
21
+ use rspack_util:: { itoa, json_stringify } ;
24
22
use swc_core:: atoms:: Atom ;
25
23
use wasmparser:: { Import , Parser , Payload } ;
26
24
@@ -35,6 +33,13 @@ pub struct AsyncWasmParserAndGenerator {
35
33
36
34
pub ( crate ) static WASM_SOURCE_TYPE : & [ SourceType ; 2 ] = & [ SourceType :: Wasm , SourceType :: JavaScript ] ;
37
35
36
+ #[ derive( Debug ) ]
37
+ struct DepModule < ' a > {
38
+ request : & ' a str ,
39
+ import_var : String ,
40
+ deps : Vec < ( DependencyId , Atom ) > ,
41
+ }
42
+
38
43
#[ cacheable_dyn]
39
44
#[ async_trait:: async_trait]
40
45
impl ParserAndGenerator for AsyncWasmParserAndGenerator {
@@ -160,8 +165,7 @@ impl ParserAndGenerator for AsyncWasmParserAndGenerator {
160
165
runtime_requirements. insert ( RuntimeGlobals :: EXPORTS ) ;
161
166
runtime_requirements. insert ( RuntimeGlobals :: INSTANTIATE_WASM ) ;
162
167
163
- let mut dep_modules = IndexMap :: < ModuleIdentifier , ( String , & ModuleId ) > :: new ( ) ;
164
- let mut wasm_deps_by_request = IndexMap :: < & str , Vec < ( Identifier , String , String ) > > :: new ( ) ;
168
+ let mut dep_modules = IndexMap :: < ModuleIdentifier , DepModule > :: new ( ) ;
165
169
let mut promises: Vec < String > = vec ! [ ] ;
166
170
167
171
let module_graph = & compilation. get_module_graph ( ) ;
@@ -170,7 +174,7 @@ impl ParserAndGenerator for AsyncWasmParserAndGenerator {
170
174
. get_dependencies ( )
171
175
. iter ( )
172
176
. map ( |id| module_graph. dependency_by_id ( id) . expect ( "should be ok" ) )
173
- . filter ( |dep| dep. dependency_type ( ) == & WasmImport )
177
+ . filter ( |dep| dep. dependency_type ( ) == & DependencyType :: WasmImport )
174
178
. map ( |dep| {
175
179
(
176
180
dep,
@@ -179,78 +183,80 @@ impl ParserAndGenerator for AsyncWasmParserAndGenerator {
179
183
} )
180
184
. for_each ( |( dep, mgm) | {
181
185
if let Some ( mgm) = mgm {
182
- if !dep_modules. contains_key ( & mgm. module_identifier ) {
183
- let mut len_buffer = itoa:: Buffer :: new ( ) ;
184
- let len_str = len_buffer. format ( dep_modules. len ( ) ) ;
185
- let import_var = format ! ( "WEBPACK_IMPORTED_MODULE_{}" , len_str) ;
186
- let val = (
187
- import_var. clone ( ) ,
188
- ChunkGraph :: get_module_id (
189
- & compilation. module_ids_artifact ,
190
- mgm. module_identifier ,
191
- )
192
- . expect ( "should have module id" ) ,
193
- ) ;
194
-
195
- if ModuleGraph :: is_async ( compilation, & mgm. module_identifier ) {
196
- promises. push ( import_var) ;
197
- }
198
- dep_modules. insert ( mgm. module_identifier , val) ;
199
- }
200
-
201
186
let dep = dep
202
187
. as_any ( )
203
188
. downcast_ref :: < WasmImportDependency > ( )
204
189
. expect ( "should be wasm import dependency" ) ;
205
-
206
- let dep_name = serde_json:: to_string ( dep. name ( ) ) . expect ( "should be ok." ) ;
207
- let Some ( UsedName :: Normal ( used_name) ) = ExportsInfoGetter :: get_used_name (
208
- GetUsedNameParam :: WithNames ( & module_graph. get_prefetched_exports_info (
209
- & mgm. module_identifier ,
210
- PrefetchExportsInfoMode :: Default ,
211
- ) ) ,
212
- * runtime,
213
- & [ dep. name ( ) . into ( ) ] ,
214
- ) else {
215
- return ;
216
- } ;
217
190
let request = dep. request ( ) ;
218
- let val = (
219
- mgm. module_identifier ,
220
- dep_name,
221
- property_access ( used_name, 0 ) ,
222
- ) ;
223
- if let Some ( deps) = wasm_deps_by_request. get_mut ( & request) {
224
- deps. push ( val) ;
225
- } else {
226
- wasm_deps_by_request. insert ( request, vec ! [ val] ) ;
227
- }
191
+ let len = dep_modules. len ( ) ;
192
+ let dep_module = dep_modules. entry ( mgm. module_identifier ) . or_insert_with ( || {
193
+ let mut len_buffer = itoa:: Buffer :: new ( ) ;
194
+ let len_str = len_buffer. format ( len) ;
195
+ let import_var = format ! ( "WEBPACK_IMPORTED_MODULE_{}" , len_str) ;
196
+ if ModuleGraph :: is_async ( compilation, & mgm. module_identifier ) {
197
+ promises. push ( import_var. clone ( ) ) ;
198
+ }
199
+ DepModule {
200
+ request,
201
+ import_var,
202
+ deps : vec ! [ ] ,
203
+ }
204
+ } ) ;
205
+ dep_module. deps . push ( ( * dep. id ( ) , dep. name ( ) . clone ( ) ) ) ;
228
206
}
229
207
} ) ;
230
208
231
- let imports_code = dep_modules
209
+ let ( imports_code, imports_compat_code ) : ( Vec < String > , Vec < String > ) = dep_modules
232
210
. iter ( )
233
- . map ( |( _, val) | render_import_stmt ( & val. 0 , val. 1 ) )
234
- . collect :: < Vec < _ > > ( )
235
- . join ( "" ) ;
236
-
237
- let import_obj_request_items = wasm_deps_by_request
238
- . into_iter ( )
239
- . map ( |( request, deps) | {
240
- let deps = deps
211
+ . map ( |( _, dep_module) | {
212
+ import_statement (
213
+ module,
214
+ compilation,
215
+ runtime_requirements,
216
+ & dep_module. deps [ 0 ] . 0 ,
217
+ & dep_module. import_var ,
218
+ dep_module. request ,
219
+ false ,
220
+ )
221
+ } )
222
+ . unzip ( ) ;
223
+ let imports_code = imports_code. join ( "" ) ;
224
+ let imports_compat_code = imports_compat_code. join ( "" ) ;
225
+
226
+ let mut template_context = TemplateContext {
227
+ compilation,
228
+ module,
229
+ runtime_requirements,
230
+ init_fragments : & mut ModuleInitFragments :: default ( ) ,
231
+ runtime : * runtime,
232
+ concatenation_scope : None ,
233
+ data : & mut CodeGenerationData :: default ( ) ,
234
+ } ;
235
+ let import_obj_request_items = dep_modules
236
+ . into_values ( )
237
+ . map ( |dep_module| {
238
+ let deps = dep_module
239
+ . deps
241
240
. into_iter ( )
242
- . map ( |( id, name, used_name) | {
243
- let import_var = dep_modules. get ( & id) . expect ( "should be ok" ) ;
244
- let import_var = & import_var. 0 ;
245
- format ! ( "{name}: {import_var}{used_name}" )
241
+ . map ( |( dep_id, export_name) | {
242
+ let export = export_from_import (
243
+ & mut template_context,
244
+ true ,
245
+ dep_module. request ,
246
+ & dep_module. import_var ,
247
+ std:: slice:: from_ref ( & export_name) ,
248
+ & dep_id,
249
+ false ,
250
+ false ,
251
+ Some ( true ) ,
252
+ ) ;
253
+ let name = json_stringify ( & export_name) ;
254
+ format ! ( "{name}: {export}" )
246
255
} )
247
256
. collect :: < Vec < _ > > ( )
248
257
. join ( ",\n " ) ;
249
258
250
- format ! (
251
- "{}: {{\n {deps}\n }}" ,
252
- serde_json:: to_string( request) . expect( "should be ok" )
253
- )
259
+ format ! ( "{}: {{\n {deps}\n }}" , json_stringify( dep_module. request) )
254
260
} )
255
261
. collect :: < Vec < _ > > ( ) ;
256
262
@@ -276,15 +282,15 @@ impl ParserAndGenerator for AsyncWasmParserAndGenerator {
276
282
. insert ( RuntimeGlobals :: ASYNC_MODULE ) ;
277
283
let promises = promises. join ( ", " ) ;
278
284
let decl = format ! (
279
- "var __webpack_instantiate__ = function ([{promises}]) {{\n return {instantiate_call};\n }}\n " ,
285
+ "var __webpack_instantiate__ = function ([{promises}]) {{\n {imports_compat_code}return {instantiate_call};\n }}\n " ,
280
286
) ;
281
287
let async_dependencies = format ! (
282
288
"{}(module, async function (__webpack_handle_async_dependencies__, __webpack_async_result__) {{
283
289
try {{
284
- {imports_code}
290
+ {imports_code}
285
291
var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([{promises}]);
286
292
var [{promises}] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__;
287
- await {instantiate_call};
293
+ {imports_compat_code} await {instantiate_call};
288
294
289
295
__webpack_async_result__();
290
296
@@ -297,7 +303,7 @@ impl ParserAndGenerator for AsyncWasmParserAndGenerator {
297
303
RawStringSource :: from ( format ! ( "{decl}{async_dependencies}" ) )
298
304
} else {
299
305
RawStringSource :: from ( format ! (
300
- "{imports_code} module.exports = {instantiate_call};"
306
+ "{imports_code}{imports_compat_code} module.exports = {instantiate_call};"
301
307
) )
302
308
} ;
303
309
@@ -339,11 +345,6 @@ async fn render_wasm_name(
339
345
. await
340
346
}
341
347
342
- fn render_import_stmt ( import_var : & str , module_id : & ModuleId ) -> String {
343
- let module_id = serde_json:: to_string ( module_id) . expect ( "TODO" ) ;
344
- format ! ( "var {import_var} = __webpack_require__({module_id});\n " , )
345
- }
346
-
347
348
fn hash_for_source ( source : & BoxSource ) -> String {
348
349
let mut hasher = DefaultHasher :: new ( ) ;
349
350
source. hash ( & mut hasher) ;
0 commit comments