turbopack_ecmascript/chunk/
mod.rs1pub(crate) mod batch;
2pub(crate) mod chunk_type;
3pub(crate) mod code_and_ids;
4pub(crate) mod content;
5pub(crate) mod data;
6pub(crate) mod item;
7pub(crate) mod placeable;
8
9use std::fmt::Write;
10
11use anyhow::Result;
12use turbo_rcstr::{RcStr, rcstr};
13use turbo_tasks::{ResolvedVc, TryJoinIterExt, ValueToString, Vc};
14use turbo_tasks_fs::FileSystem;
15use turbopack_core::{
16 chunk::{Chunk, ChunkItem, ChunkItems, ChunkingContext, ModuleIds},
17 ident::AssetIdent,
18 introspect::{
19 Introspectable, IntrospectableChildren, module::IntrospectableModule,
20 utils::children_from_output_assets,
21 },
22 output::{OutputAssetsReference, OutputAssetsWithReferenced},
23 server_fs::ServerFileSystem,
24};
25
26pub use self::{
27 batch::{
28 EcmascriptChunkBatchWithAsyncInfo, EcmascriptChunkItemBatchGroup,
29 EcmascriptChunkItemOrBatchWithAsyncInfo,
30 },
31 chunk_type::EcmascriptChunkType,
32 code_and_ids::{BatchGroupCodeAndIds, CodeAndIds, batch_group_code_and_ids, item_code_and_ids},
33 content::EcmascriptChunkContent,
34 data::EcmascriptChunkData,
35 item::{
36 EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemExt,
37 EcmascriptChunkItemOptions, EcmascriptChunkItemWithAsyncInfo,
38 },
39 placeable::{EcmascriptChunkPlaceable, EcmascriptExports},
40};
41
42#[turbo_tasks::value]
43pub struct EcmascriptChunk {
44 pub chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
45 pub content: ResolvedVc<EcmascriptChunkContent>,
46}
47
48#[turbo_tasks::value_impl]
49impl EcmascriptChunk {
50 #[turbo_tasks::function]
51 pub fn new(
52 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
53 content: ResolvedVc<EcmascriptChunkContent>,
54 ) -> Vc<Self> {
55 EcmascriptChunk {
56 chunking_context,
57 content,
58 }
59 .cell()
60 }
61
62 #[turbo_tasks::function]
63 pub fn entry_ids(self: Vc<Self>) -> Vc<ModuleIds> {
64 Vc::cell(Default::default())
66 }
67}
68
69#[turbo_tasks::value_impl]
70impl OutputAssetsReference for EcmascriptChunk {
71 #[turbo_tasks::function]
72 async fn references(&self) -> Result<Vc<OutputAssetsWithReferenced>> {
73 let content = self.content.await?;
74 let references = content
75 .chunk_items
76 .iter()
77 .map(async |with_info| {
78 let r = with_info.references().await?;
79 Ok((
80 r.assets.await?,
81 r.referenced_assets.await?,
82 r.references.await?,
83 ))
84 })
85 .try_join()
86 .await?;
87 Ok(OutputAssetsWithReferenced {
88 assets: ResolvedVc::cell(
89 references
90 .iter()
91 .flat_map(|(assets, _, _)| assets.into_iter().copied())
92 .collect(),
93 ),
94 referenced_assets: ResolvedVc::cell(
95 references
96 .iter()
97 .flat_map(|(_, referenced_assets, _)| referenced_assets.into_iter().copied())
98 .collect(),
99 ),
100 references: ResolvedVc::cell(
101 references
102 .iter()
103 .flat_map(|(_, _, references)| references.into_iter().copied())
104 .collect(),
105 ),
106 }
107 .cell())
108 }
109}
110
111#[turbo_tasks::value_impl]
112impl Chunk for EcmascriptChunk {
113 #[turbo_tasks::function]
114 async fn ident(&self) -> Result<Vc<AssetIdent>> {
115 let chunk_items = &*self.content.included_chunk_items().await?;
116 let mut common_path = if let Some(chunk_item) = chunk_items.first() {
117 let path = chunk_item.asset_ident().path().owned().await?;
118 Some(path)
119 } else {
120 None
121 };
122
123 for &chunk_item in chunk_items.iter() {
125 if let Some(common_path_ref) = common_path.as_mut() {
126 let path = chunk_item.asset_ident().path().await?;
127 while !path.is_inside_or_equal_ref(common_path_ref) {
128 let parent = common_path_ref.parent();
129 if parent == *common_path_ref {
130 common_path = None;
131 break;
132 }
133 *common_path_ref = parent;
134 }
135 }
136 }
137
138 let assets = chunk_items
139 .iter()
140 .map(|&chunk_item| async move {
141 Ok((
142 rcstr!("chunk item"),
143 chunk_item.content_ident().to_resolved().await?,
144 ))
145 })
146 .try_join()
147 .await?;
148
149 let ident = AssetIdent {
150 path: if let Some(common_path) = common_path {
151 common_path
152 } else {
153 ServerFileSystem::new().root().owned().await?
154 },
155 query: RcStr::default(),
156 fragment: RcStr::default(),
157 assets,
158 modifiers: Vec::new(),
159 parts: Vec::new(),
160 layer: None,
161 content_type: None,
162 };
163
164 Ok(AssetIdent::new(ident))
165 }
166
167 #[turbo_tasks::function]
168 fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
169 *self.chunking_context
170 }
171
172 #[turbo_tasks::function]
173 fn chunk_items(&self) -> Vc<ChunkItems> {
174 self.content.included_chunk_items()
175 }
176}
177
178#[turbo_tasks::value_impl]
179impl ValueToString for EcmascriptChunk {
180 #[turbo_tasks::function]
181 async fn to_string(self: Vc<Self>) -> Result<Vc<RcStr>> {
182 Ok(Vc::cell(
183 format!("chunk {}", self.ident().to_string().await?).into(),
184 ))
185 }
186}
187
188#[turbo_tasks::value_impl]
189impl EcmascriptChunk {
190 #[turbo_tasks::function]
191 pub fn chunk_content(&self) -> Vc<EcmascriptChunkContent> {
192 *self.content
193 }
194}
195
196#[turbo_tasks::value_impl]
197impl Introspectable for EcmascriptChunk {
198 #[turbo_tasks::function]
199 fn ty(&self) -> Vc<RcStr> {
200 Vc::cell(rcstr!("ecmascript chunk"))
201 }
202
203 #[turbo_tasks::function]
204 fn title(self: Vc<Self>) -> Vc<RcStr> {
205 self.ident().to_string()
206 }
207
208 #[turbo_tasks::function]
209 async fn details(self: Vc<Self>) -> Result<Vc<RcStr>> {
210 let mut details = String::new();
211 let this = self.await?;
212 details += "Chunk items:\n\n";
213 for chunk_item in this.content.included_chunk_items().await? {
214 writeln!(details, "- {}", chunk_item.asset_ident().to_string().await?)?;
215 }
216 Ok(Vc::cell(details.into()))
217 }
218
219 #[turbo_tasks::function]
220 async fn children(self: Vc<Self>) -> Result<Vc<IntrospectableChildren>> {
221 let mut children = children_from_output_assets(self.references())
222 .owned()
223 .await?;
224 for chunk_item in self.await?.content.included_chunk_items().await? {
225 children.insert((
226 rcstr!("module"),
227 IntrospectableModule::new(chunk_item.module())
228 .to_resolved()
229 .await?,
230 ));
231 }
232 Ok(Vc::cell(children))
233 }
234}