turbopack_ecmascript/tree_shake/
side_effect_module.rs1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::{ResolvedVc, TryJoinIterExt, Vc};
4use turbo_tasks_fs::FileContent;
5use turbopack_core::{
6 asset::{Asset, AssetContent},
7 chunk::{ChunkableModule, ChunkingContext, EvaluatableAsset},
8 ident::AssetIdent,
9 module::{Module, ModuleSideEffects},
10 module_graph::ModuleGraph,
11 reference::{ModuleReferences, SingleChunkableModuleReference},
12 resolve::{ExportUsage, ModulePart},
13};
14
15use crate::{
16 EcmascriptModuleAsset,
17 chunk::{EcmascriptChunkPlaceable, EcmascriptExports},
18 tree_shake::chunk_item::SideEffectsModuleChunkItem,
19};
20
21#[turbo_tasks::value]
22pub(super) struct SideEffectsModule {
23 pub module: ResolvedVc<EcmascriptModuleAsset>,
25 pub part: ModulePart,
27 pub resolved_as: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>,
29 pub side_effects: Vec<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
31}
32
33#[turbo_tasks::value_impl]
34impl SideEffectsModule {
35 #[turbo_tasks::function]
36 pub fn new(
37 module: ResolvedVc<EcmascriptModuleAsset>,
38 part: ModulePart,
39 resolved_as: ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>,
40 side_effects: Vec<ResolvedVc<Box<dyn EcmascriptChunkPlaceable>>>,
41 ) -> Vc<Self> {
42 SideEffectsModule {
43 module,
44 part,
45 resolved_as,
46 side_effects,
47 }
48 .cell()
49 }
50}
51
52#[turbo_tasks::value_impl]
53impl Module for SideEffectsModule {
54 #[turbo_tasks::function]
55 async fn ident(&self) -> Result<Vc<AssetIdent>> {
56 let mut ident = self.module.ident().owned().await?;
57 ident.parts.push(self.part.clone());
58
59 ident.add_asset(
60 rcstr!("resolved"),
61 self.resolved_as.ident().to_resolved().await?,
62 );
63
64 ident.add_modifier(rcstr!("side effects"));
65
66 for (i, side_effect) in self.side_effects.iter().enumerate() {
67 ident.add_asset(
68 RcStr::from(format!("side effect {i}")),
69 side_effect.ident().to_resolved().await?,
70 );
71 }
72
73 Ok(AssetIdent::new(ident))
74 }
75
76 #[turbo_tasks::function]
77 fn source(&self) -> Vc<turbopack_core::source::OptionSource> {
78 Vc::cell(None)
79 }
80
81 #[turbo_tasks::function]
82 async fn references(&self) -> Result<Vc<ModuleReferences>> {
83 let mut references = vec![];
84
85 references.extend(
86 self.side_effects
87 .iter()
88 .map(|side_effect| async move {
89 Ok(ResolvedVc::upcast(
90 SingleChunkableModuleReference::new(
91 *ResolvedVc::upcast(*side_effect),
92 rcstr!("side effect"),
93 ExportUsage::evaluation(),
94 )
95 .to_resolved()
96 .await?,
97 ))
98 })
99 .try_join()
100 .await?,
101 );
102
103 references.push(ResolvedVc::upcast(
104 SingleChunkableModuleReference::new(
105 *ResolvedVc::upcast(self.resolved_as),
106 rcstr!("resolved as"),
107 ExportUsage::all(),
108 )
109 .to_resolved()
110 .await?,
111 ));
112
113 Ok(Vc::cell(references))
114 }
115
116 #[turbo_tasks::function]
117 fn side_effects(self: Vc<Self>) -> Vc<ModuleSideEffects> {
118 ModuleSideEffects::ModuleEvaluationIsSideEffectFree.cell()
122 }
123}
124
125#[turbo_tasks::value_impl]
126impl Asset for SideEffectsModule {
127 #[turbo_tasks::function]
128 fn content(&self) -> Vc<AssetContent> {
129 AssetContent::File(
130 FileContent::Content(
131 "// This is a proxy module for reexportings a module with additional side effects."
132 .into(),
133 )
134 .resolved_cell(),
135 )
136 .cell()
137 }
138}
139
140#[turbo_tasks::value_impl]
141impl EcmascriptChunkPlaceable for SideEffectsModule {
142 #[turbo_tasks::function]
143 fn get_exports(&self) -> Vc<EcmascriptExports> {
144 self.resolved_as.get_exports()
145 }
146}
147
148#[turbo_tasks::value_impl]
149impl ChunkableModule for SideEffectsModule {
150 #[turbo_tasks::function]
151 async fn as_chunk_item(
152 self: Vc<Self>,
153 module_graph: ResolvedVc<ModuleGraph>,
154 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
155 ) -> Result<Vc<Box<dyn turbopack_core::chunk::ChunkItem>>> {
156 Ok(Vc::upcast(
157 SideEffectsModuleChunkItem {
158 module: self.to_resolved().await?,
159 module_graph,
160 chunking_context,
161 }
162 .cell(),
163 ))
164 }
165}
166
167#[turbo_tasks::value_impl]
168impl EvaluatableAsset for SideEffectsModule {}