Skip to main content

turbopack_ecmascript/chunk/
chunk_type.rs

1use anyhow::{Result, bail};
2use turbo_tasks::{ResolvedVc, TryJoinIterExt, ValueDefault, ValueToString, Vc};
3use turbopack_core::chunk::{
4    AsyncModuleInfo, Chunk, ChunkItem, ChunkItemBatchGroup, ChunkItemOrBatchWithAsyncModuleInfo,
5    ChunkType, ChunkingContext, round_chunk_item_size,
6};
7
8use super::{EcmascriptChunk, EcmascriptChunkContent, EcmascriptChunkItem};
9use crate::chunk::batch::{EcmascriptChunkItemBatchGroup, EcmascriptChunkItemOrBatchWithAsyncInfo};
10
11#[turbo_tasks::value]
12#[derive(Default, ValueToString)]
13#[value_to_string("ecmascript")]
14pub struct EcmascriptChunkType {}
15
16#[turbo_tasks::value_impl]
17impl ChunkType for EcmascriptChunkType {
18    #[turbo_tasks::function]
19    fn is_style(self: Vc<Self>) -> Vc<bool> {
20        Vc::cell(false)
21    }
22
23    #[turbo_tasks::function]
24    async fn chunk(
25        &self,
26        chunking_context: Vc<Box<dyn ChunkingContext>>,
27        chunk_items: Vec<ChunkItemOrBatchWithAsyncModuleInfo>,
28        batch_groups: Vec<ResolvedVc<ChunkItemBatchGroup>>,
29        component_chunks: Vec<ResolvedVc<Box<dyn Chunk>>>,
30    ) -> Result<Vc<Box<dyn Chunk>>> {
31        let content = EcmascriptChunkContent {
32            chunk_items: chunk_items
33                .iter()
34                .map(EcmascriptChunkItemOrBatchWithAsyncInfo::from_chunk_item_or_batch)
35                .try_join()
36                .await?,
37            batch_groups: batch_groups
38                .into_iter()
39                .map(|batch_group| {
40                    EcmascriptChunkItemBatchGroup::from_chunk_item_batch_group(*batch_group)
41                        .to_resolved()
42                })
43                .try_join()
44                .await?,
45        }
46        .cell();
47        Ok(Vc::upcast(EcmascriptChunk::new(
48            chunking_context,
49            content,
50            ResolvedVc::deref_vec(component_chunks),
51        )))
52    }
53
54    #[turbo_tasks::function]
55    async fn chunk_item_size(
56        &self,
57        _chunking_context: Vc<Box<dyn ChunkingContext>>,
58        chunk_item: ResolvedVc<Box<dyn ChunkItem>>,
59        async_module_info: Option<Vc<AsyncModuleInfo>>,
60    ) -> Result<Vc<usize>> {
61        let Some(chunk_item) = ResolvedVc::try_downcast::<Box<dyn EcmascriptChunkItem>>(chunk_item)
62        else {
63            bail!("Chunk item is not an ecmascript chunk item but reporting chunk type ecmascript");
64        };
65        let chunk_item = chunk_item.into_trait_ref().await?;
66        let size = match chunk_item
67            .content_with_async_module_info(async_module_info, true)
68            .await
69        {
70            Ok(content) => {
71                let content = content.await?;
72                round_chunk_item_size(content.inner_code.len())
73            }
74            Err(_) => 0,
75        };
76        Ok(Vc::cell(size))
77    }
78}
79
80#[turbo_tasks::value_impl]
81impl ValueDefault for EcmascriptChunkType {
82    #[turbo_tasks::function]
83    fn value_default() -> Vc<Self> {
84        Self::default().cell()
85    }
86}