rspack_plugin_javascript/dependency/esm/
esm_compatibility_dependency.rs1use rspack_cacheable::{cacheable, cacheable_dyn};
2use rspack_core::{
3 DependencyCodeGeneration, DependencyTemplate, DependencyTemplateType, InitFragmentKey,
4 InitFragmentStage, ModuleGraph, NormalInitFragment, PrefetchExportsInfoMode, RuntimeGlobals,
5 TemplateContext, TemplateReplaceSource, UsageState,
6};
7use swc_core::atoms::Atom;
8
9#[cacheable]
12#[derive(Debug, Clone)]
13pub struct ESMCompatibilityDependency;
14
15#[cacheable_dyn]
16impl DependencyCodeGeneration for ESMCompatibilityDependency {
17 fn dependency_template(&self) -> Option<DependencyTemplateType> {
18 Some(ESMCompatibilityDependencyTemplate::template_type())
19 }
20}
21
22#[cacheable]
23#[derive(Debug, Default)]
24pub struct ESMCompatibilityDependencyTemplate;
25
26impl ESMCompatibilityDependencyTemplate {
27 pub fn template_type() -> DependencyTemplateType {
28 DependencyTemplateType::Custom("ESMCompatibilityDependency")
29 }
30}
31
32impl DependencyTemplate for ESMCompatibilityDependencyTemplate {
33 fn render(
34 &self,
35 _dep: &dyn DependencyCodeGeneration,
36 _source: &mut TemplateReplaceSource,
37 code_generatable_context: &mut TemplateContext,
38 ) {
39 let TemplateContext {
40 runtime_requirements,
41 init_fragments,
42 compilation,
43 module,
44 runtime,
45 concatenation_scope,
46 ..
47 } = code_generatable_context;
48 if concatenation_scope.is_some() {
49 return;
50 }
51 let module_graph = compilation.get_module_graph();
52 let module = module_graph
53 .module_by_identifier(&module.identifier())
54 .expect("should have mgm");
55 let name = Atom::from("__esModule");
56 let exports_info = module_graph
57 .get_prefetched_exports_info(&module.identifier(), PrefetchExportsInfoMode::Default);
58 let used = exports_info
59 .get_read_only_export_info(&name)
60 .get_used(*runtime);
61 if !matches!(used, UsageState::Unused) {
62 runtime_requirements.insert(RuntimeGlobals::MAKE_NAMESPACE_OBJECT);
63 runtime_requirements.insert(RuntimeGlobals::EXPORTS);
64 init_fragments.push(Box::new(NormalInitFragment::new(
65 format!(
66 "{}({});\n",
67 compilation
68 .runtime_template
69 .render_runtime_globals(&RuntimeGlobals::MAKE_NAMESPACE_OBJECT),
70 compilation
71 .runtime_template
72 .render_exports_argument(module.get_exports_argument()),
73 ),
74 InitFragmentStage::StageESMExports,
75 0,
76 InitFragmentKey::ESMCompatibility,
77 None,
78 )));
79 }
80
81 if ModuleGraph::is_async(
82 &compilation.async_modules_artifact.borrow(),
83 &module.identifier(),
84 ) {
85 runtime_requirements.insert(RuntimeGlobals::MODULE);
86 runtime_requirements.insert(RuntimeGlobals::ASYNC_MODULE);
87 init_fragments.push(Box::new(NormalInitFragment::new(
88 format!(
89 "{}({}, async function (__rspack_load_async_deps, __rspack_async_done) {{ try {{\n",
90 compilation
91 .runtime_template
92 .render_runtime_globals(&RuntimeGlobals::ASYNC_MODULE),
93 compilation.runtime_template.render_module_argument(
94 module_graph
95 .module_by_identifier(&module.identifier())
96 .expect("should have mgm")
97 .get_module_argument()
98 ),
99 ),
100 InitFragmentStage::StageAsyncBoundary,
101 0,
102 InitFragmentKey::unique(),
103 Some(format!(
104 "\n__rspack_async_done();\n}} catch(e) {{ __rspack_async_done(e); }} }}{});",
105 if module.build_meta().has_top_level_await {
106 ", 1"
107 } else {
108 ""
109 }
110 )),
111 )));
112 }
113 }
114}