Skip to content

Commit 7473a29

Browse files
authored
feat: support import.defer() for context module (#12938)
1 parent 5ee65b4 commit 7473a29

File tree

36 files changed

+631
-371
lines changed

36 files changed

+631
-371
lines changed

crates/rspack_core/src/context_module.rs

Lines changed: 197 additions & 110 deletions
Large diffs are not rendered by default.

crates/rspack_core/src/dependency/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,14 @@ impl ImportPhase {
230230
pub fn is_defer(&self) -> bool {
231231
matches!(self, ImportPhase::Defer)
232232
}
233+
234+
pub fn as_str(&self) -> &'static str {
235+
match self {
236+
ImportPhase::Evaluation => "evaluation",
237+
ImportPhase::Source => "source",
238+
ImportPhase::Defer => "defer",
239+
}
240+
}
233241
}
234242

235243
impl From<swc_core::ecma::ast::ImportPhase> for ImportPhase {

crates/rspack_core/src/runtime_template.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,10 +430,10 @@ where
430430

431431
pub fn render_make_deferred_namespace_mode_from_exports_type(exports_type: ExportsType) -> String {
432432
match exports_type {
433-
ExportsType::Namespace => "0".to_string(),
434-
ExportsType::DefaultOnly => "1".to_string(),
433+
ExportsType::Namespace => "8".to_string(),
434+
ExportsType::DefaultOnly => "0".to_string(),
435435
ExportsType::DefaultWithNamed => "2".to_string(),
436-
ExportsType::Dynamic => "3".to_string(),
436+
ExportsType::Dynamic => "6".to_string(),
437437
}
438438
}
439439

@@ -465,7 +465,7 @@ pub fn get_exports_type_with_strict(
465465
.get_exports_type(module_graph, module_graph_cache, strict)
466466
}
467467

468-
fn get_outgoing_async_modules(
468+
pub fn get_outgoing_async_modules(
469469
compilation: &Compilation,
470470
module: &dyn Module,
471471
) -> FxIndexSet<ModuleId> {
@@ -1255,7 +1255,10 @@ impl ModuleCodegenRuntimeTemplate {
12551255
let mut appending;
12561256

12571257
if phase.is_defer() && !target_module.build_meta().has_top_level_await {
1258-
let mode = render_make_deferred_namespace_mode_from_exports_type(exports_type);
1258+
let mode = format!(
1259+
"{} | 16",
1260+
render_make_deferred_namespace_mode_from_exports_type(exports_type)
1261+
);
12591262
let async_deps = get_outgoing_async_modules(compilation, target_module.as_ref());
12601263
if !async_deps.is_empty() {
12611264
if let Some(header) = header {

crates/rspack_plugin_javascript/src/dependency/context/import_context_dependency.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rspack_cacheable::{cacheable, cacheable_dyn};
2+
use rspack_collections::Identifier;
23
use rspack_core::{
34
AsModuleDependency, ContextDependency, ContextOptions, Dependency, DependencyCategory,
45
DependencyCodeGeneration, DependencyId, DependencyRange, DependencyTemplate,
@@ -12,6 +13,16 @@ use super::{
1213
context_dependency_template_as_require_call, create_resource_identifier_for_context_dependency,
1314
};
1415

16+
fn create_resource_identifier(options: &ContextOptions) -> Identifier {
17+
let mut resource_identifier =
18+
create_resource_identifier_for_context_dependency(None, options).to_string();
19+
if let Some(attributes) = &options.attributes {
20+
resource_identifier
21+
.push_str(&serde_json::to_string(attributes).expect("json stringify failed"));
22+
}
23+
resource_identifier.into()
24+
}
25+
1526
#[cacheable]
1627
#[derive(Debug, Clone)]
1728
pub struct ImportContextDependency {
@@ -32,26 +43,21 @@ impl ImportContextDependency {
3243
value_range: DependencyRange,
3344
optional: bool,
3445
) -> Self {
35-
let mut resource_identifier =
36-
create_resource_identifier_for_context_dependency(None, &options).to_string();
37-
if let Some(attributes) = &options.attributes {
38-
resource_identifier
39-
.push_str(&serde_json::to_string(attributes).expect("json stringify failed"));
40-
}
4146
Self {
42-
options,
47+
id: DependencyId::new(),
48+
resource_identifier: create_resource_identifier(&options),
4349
range,
4450
value_range,
45-
id: DependencyId::new(),
46-
resource_identifier: resource_identifier.into(),
4751
optional,
4852
critical: None,
4953
factorize_info: Default::default(),
54+
options,
5055
}
5156
}
5257

5358
pub fn set_referenced_exports(&mut self, referenced_exports: Vec<Vec<Atom>>) {
5459
self.options.referenced_exports = Some(referenced_exports);
60+
self.resource_identifier = create_resource_identifier(&self.options);
5561
}
5662
}
5763

crates/rspack_plugin_javascript/src/parser_plugin/amd/amd_define_dependency_parser_plugin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ impl AMDDefineDependencyParserPlugin {
260260
end: call_span.real_hi(),
261261
referenced_exports: None,
262262
attributes: None,
263+
phase: None,
263264
};
264265
let mut dep = AMDRequireContextDependency::new(options, param_range.into(), parser.in_try);
265266
*dep.critical_mut() = result.critical;

crates/rspack_plugin_javascript/src/parser_plugin/amd/amd_require_dependencies_block_parser_plugin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ impl AMDRequireDependenciesBlockParserPlugin {
190190
end: call_span.real_hi(),
191191
referenced_exports: None,
192192
attributes: None,
193+
phase: None,
193194
};
194195
let mut dep = AMDRequireContextDependency::new(options, param_range.into(), parser.in_try);
195196
*dep.critical_mut() = result.critical;

crates/rspack_plugin_javascript/src/parser_plugin/common_js_imports_parse_plugin.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fn create_commonjs_require_context_dependency(
5151
end: span.real_hi(),
5252
referenced_exports: None,
5353
attributes: None,
54+
phase: None,
5455
};
5556
let mut dep = CommonJsRequireContextDependency::new(
5657
options,
@@ -96,6 +97,7 @@ fn create_require_resolve_context_dependency(
9697
end,
9798
referenced_exports: None,
9899
attributes: None,
100+
phase: None,
99101
};
100102
RequireResolveContextDependency::new(options, range, parser.in_try)
101103
}
@@ -397,6 +399,7 @@ impl CommonJsImportsParserPlugin {
397399
end,
398400
referenced_exports: None,
399401
attributes: None,
402+
phase: None,
400403
},
401404
DependencyRange::from(span)
402405
.to_loc(Some(parser.source()))

crates/rspack_plugin_javascript/src/parser_plugin/import_meta_context_dependency_parser_plugin.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ fn create_import_meta_context_dependency(
7676
end: node.span().real_hi(),
7777
referenced_exports: None,
7878
attributes: None,
79+
phase: None,
7980
}
8081
} else {
8182
ContextOptions {
@@ -94,6 +95,7 @@ fn create_import_meta_context_dependency(
9495
end: node.span().real_hi(),
9596
referenced_exports: None,
9697
attributes: None,
98+
phase: None,
9799
}
98100
};
99101
Some(ImportMetaContextDependency::new(

crates/rspack_plugin_javascript/src/parser_plugin/import_parser_plugin.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,6 @@ impl JavascriptParserPlugin for ImportParserPlugin {
390390
return None;
391391
}
392392

393-
if phase.is_defer() {
394-
parser.add_error(rspack_error::error!("import.defer() is not yet supported for ContextModule (the import path is a dynamic expression).").into());
395-
}
396-
397393
let ContextModuleScanResult {
398394
context,
399395
reg,
@@ -430,6 +426,7 @@ impl JavascriptParserPlugin for ImportParserPlugin {
430426
end: import_call_span.real_hi(),
431427
referenced_exports: exports,
432428
attributes,
429+
phase: Some(phase),
433430
},
434431
import_call_span.into(),
435432
dyn_imported.span().into(),

crates/rspack_plugin_javascript/src/parser_plugin/require_context_dependency_parser_plugin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ impl JavascriptParserPlugin for RequireContextDependencyParserPlugin {
8888
end: expr.span().real_hi(),
8989
referenced_exports: None,
9090
attributes: None,
91+
phase: None,
9192
},
9293
expr.span.into(),
9394
parser.in_try,

0 commit comments

Comments
 (0)