turbopack_core/chunk/
chunking_context.rs

1use anyhow::{Result, bail};
2use rustc_hash::FxHashMap;
3use serde::{Deserialize, Serialize};
4use turbo_rcstr::RcStr;
5use turbo_tasks::{NonLocalValue, ResolvedVc, TaskInput, Upcast, Vc, trace::TraceRawVcs};
6use turbo_tasks_fs::FileSystemPath;
7use turbo_tasks_hash::DeterministicHash;
8
9use super::{ChunkableModule, EvaluatableAssets, availability_info::AvailabilityInfo};
10use crate::{
11    asset::Asset,
12    chunk::{ChunkItem, ChunkType, ModuleId},
13    environment::Environment,
14    ident::AssetIdent,
15    module::Module,
16    module_graph::{
17        ModuleGraph, chunk_group_info::ChunkGroup, export_usage::ModuleExportUsage,
18        module_batches::BatchingConfig,
19    },
20    output::{
21        ExpandOutputAssetsInput, OutputAsset, OutputAssets, OutputAssetsReferences,
22        OutputAssetsWithReferenced, expand_output_assets,
23    },
24};
25
26#[derive(
27    Debug,
28    TaskInput,
29    Clone,
30    Copy,
31    PartialEq,
32    Eq,
33    Hash,
34    Serialize,
35    Deserialize,
36    TraceRawVcs,
37    DeterministicHash,
38    NonLocalValue,
39)]
40#[serde(rename_all = "kebab-case")]
41pub enum MangleType {
42    OptimalSize,
43    Deterministic,
44}
45
46#[turbo_tasks::value(shared)]
47#[derive(Debug, TaskInput, Clone, Copy, Hash, DeterministicHash)]
48pub enum MinifyType {
49    // TODO instead of adding a new property here,
50    // refactor that to Minify(MinifyOptions) to allow defaults on MinifyOptions
51    Minify { mangle: Option<MangleType> },
52    NoMinify,
53}
54
55impl Default for MinifyType {
56    fn default() -> Self {
57        Self::Minify {
58            mangle: Some(MangleType::OptimalSize),
59        }
60    }
61}
62
63#[turbo_tasks::value(shared)]
64#[derive(Debug, Default, TaskInput, Clone, Copy, Hash, DeterministicHash)]
65pub enum SourceMapsType {
66    /// Extracts source maps from input files and writes source maps for output files.
67    #[default]
68    Full,
69    /// Ignores the existence of source maps and does not write source maps for output files.
70    None,
71}
72
73#[derive(
74    Debug,
75    TaskInput,
76    Clone,
77    Copy,
78    PartialEq,
79    Eq,
80    Hash,
81    Serialize,
82    Deserialize,
83    TraceRawVcs,
84    DeterministicHash,
85    NonLocalValue,
86)]
87pub enum ChunkGroupType {
88    Entry,
89    Evaluated,
90}
91
92#[turbo_tasks::value(shared)]
93#[derive(Clone)]
94pub struct ChunkGroupResult {
95    pub assets: ResolvedVc<OutputAssets>,
96    pub referenced_assets: ResolvedVc<OutputAssets>,
97    pub references: ResolvedVc<OutputAssetsReferences>,
98    pub availability_info: AvailabilityInfo,
99}
100
101impl ChunkGroupResult {
102    pub fn empty() -> Vc<Self> {
103        ChunkGroupResult {
104            assets: ResolvedVc::cell(vec![]),
105            referenced_assets: ResolvedVc::cell(vec![]),
106            references: ResolvedVc::cell(vec![]),
107            availability_info: AvailabilityInfo::root(),
108        }
109        .cell()
110    }
111
112    pub fn empty_resolved() -> ResolvedVc<Self> {
113        ChunkGroupResult {
114            assets: ResolvedVc::cell(vec![]),
115            referenced_assets: ResolvedVc::cell(vec![]),
116            references: ResolvedVc::cell(vec![]),
117            availability_info: AvailabilityInfo::root(),
118        }
119        .resolved_cell()
120    }
121}
122
123#[turbo_tasks::value_impl]
124impl ChunkGroupResult {
125    #[turbo_tasks::function]
126    pub async fn output_assets_with_referenced(&self) -> Result<Vc<OutputAssetsWithReferenced>> {
127        Ok(OutputAssetsWithReferenced {
128            assets: self.assets,
129            referenced_assets: self.referenced_assets,
130            references: self.references,
131        }
132        .cell())
133    }
134
135    #[turbo_tasks::function]
136    pub async fn concatenate(&self, next: Vc<Self>) -> Result<Vc<Self>> {
137        let next = next.await?;
138        Ok(ChunkGroupResult {
139            assets: self.assets.concatenate(*next.assets).to_resolved().await?,
140            referenced_assets: self
141                .referenced_assets
142                .concatenate(*next.referenced_assets)
143                .to_resolved()
144                .await?,
145            references: self
146                .references
147                .concatenate(*next.references)
148                .to_resolved()
149                .await?,
150            availability_info: next.availability_info,
151        }
152        .cell())
153    }
154
155    #[turbo_tasks::function]
156    pub async fn all_assets(&self) -> Result<Vc<OutputAssets>> {
157        Ok(Vc::cell(
158            expand_output_assets(
159                self.assets
160                    .await?
161                    .into_iter()
162                    .chain(self.referenced_assets.await?.into_iter())
163                    .copied()
164                    .map(ExpandOutputAssetsInput::Asset)
165                    .chain(
166                        self.references
167                            .await?
168                            .into_iter()
169                            .copied()
170                            .map(ExpandOutputAssetsInput::Reference),
171                    ),
172                false,
173            )
174            .await?,
175        ))
176    }
177
178    /// Returns only primary asset entries. Doesn't expand OutputAssets. Doesn't return referenced
179    /// assets.
180    #[turbo_tasks::function]
181    pub fn primary_assets(&self) -> Vc<OutputAssets> {
182        *self.assets
183    }
184
185    #[turbo_tasks::function]
186    pub async fn referenced_assets(&self) -> Result<Vc<OutputAssets>> {
187        Ok(Vc::cell(
188            expand_output_assets(
189                self.referenced_assets
190                    .await?
191                    .into_iter()
192                    .copied()
193                    .map(ExpandOutputAssetsInput::Asset)
194                    .chain(
195                        self.references
196                            .await?
197                            .into_iter()
198                            .copied()
199                            .map(ExpandOutputAssetsInput::Reference),
200                    ),
201                false,
202            )
203            .await?,
204        ))
205    }
206}
207
208#[turbo_tasks::value(shared)]
209pub struct EntryChunkGroupResult {
210    pub asset: ResolvedVc<Box<dyn OutputAsset>>,
211    pub availability_info: AvailabilityInfo,
212}
213
214#[derive(
215    Default,
216    Debug,
217    Clone,
218    PartialEq,
219    Eq,
220    Hash,
221    Serialize,
222    Deserialize,
223    TraceRawVcs,
224    NonLocalValue,
225    TaskInput,
226)]
227pub struct ChunkingConfig {
228    /// Try to avoid creating more than 1 chunk smaller than this size.
229    /// It merges multiple small chunks into bigger ones to avoid that.
230    pub min_chunk_size: usize,
231
232    /// Try to avoid creating more than this number of chunks per group.
233    /// It merges multiple chunks into bigger ones to avoid that.
234    pub max_chunk_count_per_group: usize,
235
236    /// Never merges chunks bigger than this size with other chunks.
237    /// This makes sure that code in big chunks is not duplicated in multiple chunks.
238    pub max_merge_chunk_size: usize,
239
240    #[allow(dead_code)]
241    pub placeholder_for_future_extensions: (),
242}
243
244#[turbo_tasks::value(transparent)]
245pub struct ChunkingConfigs(FxHashMap<ResolvedVc<Box<dyn ChunkType>>, ChunkingConfig>);
246
247#[turbo_tasks::value(shared)]
248#[derive(Debug, Clone, Copy, Hash, TaskInput, Default)]
249pub enum SourceMapSourceType {
250    AbsoluteFileUri,
251    RelativeUri,
252    #[default]
253    TurbopackUri,
254}
255
256/// A context for the chunking that influences the way chunks are created
257#[turbo_tasks::value_trait]
258pub trait ChunkingContext {
259    #[turbo_tasks::function]
260    fn name(self: Vc<Self>) -> Vc<RcStr>;
261    #[turbo_tasks::function]
262    fn source_map_source_type(self: Vc<Self>) -> Vc<SourceMapSourceType>;
263    /// The root path of the project
264    #[turbo_tasks::function]
265    fn root_path(self: Vc<Self>) -> Vc<FileSystemPath>;
266    /// The output root path in the output filesystem
267    #[turbo_tasks::function]
268    fn output_root(self: Vc<Self>) -> Vc<FileSystemPath>;
269    /// A relative path how to reach the root path from the output root. This is used to compute
270    /// original paths at runtime relative to the output files. e. g. import.meta.url needs that.
271    #[turbo_tasks::function]
272    fn output_root_to_root_path(self: Vc<Self>) -> Vc<RcStr>;
273
274    // TODO remove this, a chunking context should not be bound to a specific
275    // environment since this can change due to transitions in the module graph
276    #[turbo_tasks::function]
277    fn environment(self: Vc<Self>) -> Vc<Environment>;
278
279    /// The path to the folder where all chunks are placed. This can be used to compute relative
280    /// paths.
281    #[turbo_tasks::function]
282    fn chunk_root_path(self: Vc<Self>) -> Vc<FileSystemPath>;
283
284    // TODO(alexkirsz) Remove this from the chunking context. This should be at the
285    // discretion of chunking context implementors. However, we currently use this
286    // in a couple of places in `turbopack-css`, so we need to remove that
287    // dependency first.
288    #[turbo_tasks::function]
289    fn chunk_path(
290        self: Vc<Self>,
291        asset: Option<Vc<Box<dyn Asset>>>,
292        ident: Vc<AssetIdent>,
293        content_hashing_prefix: Option<RcStr>,
294        extension: RcStr,
295    ) -> Vc<FileSystemPath>;
296
297    /// Reference Source Map Assets for chunks
298    #[turbo_tasks::function]
299    fn reference_chunk_source_maps(self: Vc<Self>, chunk: Vc<Box<dyn OutputAsset>>) -> Vc<bool>;
300
301    /// Include Source Maps for modules
302    #[turbo_tasks::function]
303    fn reference_module_source_maps(self: Vc<Self>, module: Vc<Box<dyn Module>>) -> Vc<bool>;
304
305    /// Returns a URL (relative or absolute, depending on the asset prefix) to
306    /// the static asset based on its `ident`.
307    /// The `tag` is an arbitrary string that can be used to distinguish
308    /// different usages of the same asset (e.g. different base paths).
309    #[turbo_tasks::function]
310    fn asset_url(self: Vc<Self>, ident: FileSystemPath, tag: Option<RcStr>) -> Result<Vc<RcStr>>;
311
312    #[turbo_tasks::function]
313    fn asset_path(
314        self: Vc<Self>,
315        content_hash: RcStr,
316        original_asset_ident: Vc<AssetIdent>,
317        tag: Option<RcStr>,
318    ) -> Vc<FileSystemPath>;
319
320    #[turbo_tasks::function]
321    fn is_hot_module_replacement_enabled(self: Vc<Self>) -> Vc<bool> {
322        Vc::cell(false)
323    }
324
325    #[turbo_tasks::function]
326    fn chunking_configs(self: Vc<Self>) -> Vc<ChunkingConfigs> {
327        Vc::cell(Default::default())
328    }
329
330    #[turbo_tasks::function]
331    fn batching_config(self: Vc<Self>) -> Vc<BatchingConfig> {
332        BatchingConfig::new(BatchingConfig {
333            ..Default::default()
334        })
335    }
336
337    /// Whether `ChunkingType::Traced` are used to create corresponding output assets for each
338    /// traced module.
339    #[turbo_tasks::function]
340    fn is_tracing_enabled(self: Vc<Self>) -> Vc<bool> {
341        Vc::cell(false)
342    }
343
344    /// Whether async modules should create an new availability boundary and therefore nested async
345    /// modules include less modules. Enabling this will lead to better optimized async chunks,
346    /// but it will require to compute all possible paths in the application, which might lead to
347    /// many combinations.
348    #[turbo_tasks::function]
349    fn is_nested_async_availability_enabled(self: Vc<Self>) -> Vc<bool> {
350        Vc::cell(false)
351    }
352
353    /// Whether to use `MergeableModule` to merge modules if possible.
354    #[turbo_tasks::function]
355    fn is_module_merging_enabled(self: Vc<Self>) -> Vc<bool> {
356        Vc::cell(false)
357    }
358
359    /// Whether to include information about the content of the chunk into the runtime, to allow
360    /// more incremental loading of individual chunk items.
361    #[turbo_tasks::function]
362    fn is_dynamic_chunk_content_loading_enabled(self: Vc<Self>) -> Vc<bool> {
363        Vc::cell(false)
364    }
365
366    #[turbo_tasks::function]
367    fn minify_type(self: Vc<Self>) -> Vc<MinifyType> {
368        MinifyType::NoMinify.cell()
369    }
370
371    #[turbo_tasks::function]
372    fn should_use_absolute_url_references(self: Vc<Self>) -> Vc<bool> {
373        Vc::cell(false)
374    }
375
376    #[turbo_tasks::function]
377    fn async_loader_chunk_item(
378        &self,
379        module: Vc<Box<dyn ChunkableModule>>,
380        module_graph: Vc<ModuleGraph>,
381        availability_info: AvailabilityInfo,
382    ) -> Vc<Box<dyn ChunkItem>>;
383    #[turbo_tasks::function]
384    fn async_loader_chunk_item_id(&self, module: Vc<Box<dyn ChunkableModule>>) -> Vc<ModuleId>;
385
386    #[turbo_tasks::function]
387    fn chunk_group(
388        self: Vc<Self>,
389        ident: Vc<AssetIdent>,
390        chunk_group: ChunkGroup,
391        module_graph: Vc<ModuleGraph>,
392        availability_info: AvailabilityInfo,
393    ) -> Vc<ChunkGroupResult>;
394
395    #[turbo_tasks::function]
396    fn evaluated_chunk_group(
397        self: Vc<Self>,
398        ident: Vc<AssetIdent>,
399        chunk_group: ChunkGroup,
400        module_graph: Vc<ModuleGraph>,
401        availability_info: AvailabilityInfo,
402    ) -> Vc<ChunkGroupResult>;
403
404    /// Generates an output chunk that:
405    /// * loads the given extra_chunks in addition to the generated chunks; and
406    /// * evaluates the given assets; and
407    /// * exports the result of evaluating the last module as a CommonJS default export.
408    #[turbo_tasks::function]
409    fn entry_chunk_group(
410        self: Vc<Self>,
411        path: FileSystemPath,
412        evaluatable_assets: Vc<EvaluatableAssets>,
413        module_graph: Vc<ModuleGraph>,
414        extra_chunks: Vc<OutputAssets>,
415        extra_referenced_assets: Vc<OutputAssets>,
416        availability_info: AvailabilityInfo,
417    ) -> Result<Vc<EntryChunkGroupResult>>;
418
419    #[turbo_tasks::function]
420    async fn chunk_item_id_from_ident(
421        self: Vc<Self>,
422        ident: Vc<AssetIdent>,
423    ) -> Result<Vc<ModuleId>>;
424
425    #[turbo_tasks::function]
426    fn chunk_item_id(self: Vc<Self>, module: Vc<Box<dyn ChunkItem>>) -> Vc<ModuleId> {
427        self.chunk_item_id_from_ident(module.asset_ident())
428    }
429    #[turbo_tasks::function]
430    fn chunk_item_id_from_module(self: Vc<Self>, module: Vc<Box<dyn Module>>) -> Vc<ModuleId> {
431        self.chunk_item_id_from_ident(module.ident())
432    }
433
434    #[turbo_tasks::function]
435    async fn module_export_usage(
436        self: Vc<Self>,
437        module: Vc<Box<dyn Module>>,
438    ) -> Result<Vc<ModuleExportUsage>>;
439
440    /// Returns whether debug IDs are enabled for this chunking context.
441    #[turbo_tasks::function]
442    fn debug_ids_enabled(self: Vc<Self>) -> Vc<bool>;
443}
444
445pub trait ChunkingContextExt {
446    fn root_chunk_group(
447        self: Vc<Self>,
448        ident: Vc<AssetIdent>,
449        chunk_group: ChunkGroup,
450        module_graph: Vc<ModuleGraph>,
451    ) -> Vc<ChunkGroupResult>
452    where
453        Self: Send;
454
455    fn root_chunk_group_assets(
456        self: Vc<Self>,
457        ident: Vc<AssetIdent>,
458        chunk_group: ChunkGroup,
459        module_graph: Vc<ModuleGraph>,
460    ) -> Vc<OutputAssetsWithReferenced>
461    where
462        Self: Send;
463
464    fn evaluated_chunk_group_assets(
465        self: Vc<Self>,
466        ident: Vc<AssetIdent>,
467        chunk_group: ChunkGroup,
468        module_graph: Vc<ModuleGraph>,
469        availability_info: AvailabilityInfo,
470    ) -> Vc<OutputAssetsWithReferenced>
471    where
472        Self: Send;
473
474    fn entry_chunk_group_asset(
475        self: Vc<Self>,
476        path: FileSystemPath,
477        evaluatable_assets: Vc<EvaluatableAssets>,
478        module_graph: Vc<ModuleGraph>,
479        extra_chunks: Vc<OutputAssets>,
480        extra_referenced_assets: Vc<OutputAssets>,
481        availability_info: AvailabilityInfo,
482    ) -> Vc<Box<dyn OutputAsset>>
483    where
484        Self: Send;
485
486    fn root_entry_chunk_group(
487        self: Vc<Self>,
488        path: FileSystemPath,
489        evaluatable_assets: Vc<EvaluatableAssets>,
490        module_graph: Vc<ModuleGraph>,
491        extra_chunks: Vc<OutputAssets>,
492        extra_referenced_assets: Vc<OutputAssets>,
493    ) -> Vc<EntryChunkGroupResult>
494    where
495        Self: Send;
496
497    fn root_entry_chunk_group_asset(
498        self: Vc<Self>,
499        path: FileSystemPath,
500        evaluatable_assets: Vc<EvaluatableAssets>,
501        module_graph: Vc<ModuleGraph>,
502        extra_chunks: Vc<OutputAssets>,
503        extra_referenced_assets: Vc<OutputAssets>,
504    ) -> Vc<Box<dyn OutputAsset>>
505    where
506        Self: Send;
507
508    fn chunk_group_assets(
509        self: Vc<Self>,
510        ident: Vc<AssetIdent>,
511        chunk_group: ChunkGroup,
512        module_graph: Vc<ModuleGraph>,
513        availability_info: AvailabilityInfo,
514    ) -> Vc<OutputAssetsWithReferenced>
515    where
516        Self: Send;
517
518    /// Computes the relative path from the chunk output root to the project root.
519    ///
520    /// This is used to compute relative paths for source maps in certain configurations.
521    fn relative_path_from_chunk_root_to_project_root(self: Vc<Self>) -> Vc<RcStr>
522    where
523        Self: Send;
524}
525
526impl<T: ChunkingContext + Send + Upcast<Box<dyn ChunkingContext>>> ChunkingContextExt for T {
527    fn root_chunk_group(
528        self: Vc<Self>,
529        ident: Vc<AssetIdent>,
530        chunk_group: ChunkGroup,
531        module_graph: Vc<ModuleGraph>,
532    ) -> Vc<ChunkGroupResult> {
533        self.chunk_group(ident, chunk_group, module_graph, AvailabilityInfo::root())
534    }
535
536    fn root_chunk_group_assets(
537        self: Vc<Self>,
538        ident: Vc<AssetIdent>,
539        chunk_group: ChunkGroup,
540        module_graph: Vc<ModuleGraph>,
541    ) -> Vc<OutputAssetsWithReferenced> {
542        root_chunk_group_assets(
543            Vc::upcast_non_strict(self),
544            ident,
545            chunk_group,
546            module_graph,
547        )
548    }
549
550    fn evaluated_chunk_group_assets(
551        self: Vc<Self>,
552        ident: Vc<AssetIdent>,
553        chunk_group: ChunkGroup,
554        module_graph: Vc<ModuleGraph>,
555        availability_info: AvailabilityInfo,
556    ) -> Vc<OutputAssetsWithReferenced> {
557        evaluated_chunk_group_assets(
558            Vc::upcast_non_strict(self),
559            ident,
560            chunk_group,
561            module_graph,
562            availability_info,
563        )
564    }
565
566    fn entry_chunk_group_asset(
567        self: Vc<Self>,
568        path: FileSystemPath,
569        evaluatable_assets: Vc<EvaluatableAssets>,
570        module_graph: Vc<ModuleGraph>,
571        extra_chunks: Vc<OutputAssets>,
572        extra_referenced_assets: Vc<OutputAssets>,
573        availability_info: AvailabilityInfo,
574    ) -> Vc<Box<dyn OutputAsset>> {
575        entry_chunk_group_asset(
576            Vc::upcast_non_strict(self),
577            path,
578            evaluatable_assets,
579            module_graph,
580            extra_chunks,
581            extra_referenced_assets,
582            availability_info,
583        )
584    }
585
586    fn root_entry_chunk_group(
587        self: Vc<Self>,
588        path: FileSystemPath,
589        evaluatable_assets: Vc<EvaluatableAssets>,
590        module_graph: Vc<ModuleGraph>,
591        extra_chunks: Vc<OutputAssets>,
592        extra_referenced_assets: Vc<OutputAssets>,
593    ) -> Vc<EntryChunkGroupResult> {
594        self.entry_chunk_group(
595            path,
596            evaluatable_assets,
597            module_graph,
598            extra_chunks,
599            extra_referenced_assets,
600            AvailabilityInfo::root(),
601        )
602    }
603
604    fn root_entry_chunk_group_asset(
605        self: Vc<Self>,
606        path: FileSystemPath,
607        evaluatable_assets: Vc<EvaluatableAssets>,
608        module_graph: Vc<ModuleGraph>,
609        extra_chunks: Vc<OutputAssets>,
610        extra_referenced_assets: Vc<OutputAssets>,
611    ) -> Vc<Box<dyn OutputAsset>> {
612        entry_chunk_group_asset(
613            Vc::upcast_non_strict(self),
614            path,
615            evaluatable_assets,
616            module_graph,
617            extra_chunks,
618            extra_referenced_assets,
619            AvailabilityInfo::root(),
620        )
621    }
622
623    fn chunk_group_assets(
624        self: Vc<Self>,
625        ident: Vc<AssetIdent>,
626        chunk_group: ChunkGroup,
627        module_graph: Vc<ModuleGraph>,
628        availability_info: AvailabilityInfo,
629    ) -> Vc<OutputAssetsWithReferenced> {
630        chunk_group_assets(
631            Vc::upcast_non_strict(self),
632            ident,
633            chunk_group,
634            module_graph,
635            availability_info,
636        )
637    }
638
639    fn relative_path_from_chunk_root_to_project_root(self: Vc<Self>) -> Vc<RcStr> {
640        relative_path_from_chunk_root_to_project_root(Vc::upcast_non_strict(self))
641    }
642}
643
644#[turbo_tasks::function]
645async fn relative_path_from_chunk_root_to_project_root(
646    chunking_context: Vc<Box<dyn ChunkingContext>>,
647) -> Result<Vc<RcStr>> {
648    // Example,
649    //   project root: /project/root
650    //   output root: /project/root/dist
651    //   chunk root path: /project/root/dist/ssr/chunks
652    //   output_root_to_chunk_root: ../
653    //
654    // Example2,
655    //   project root: /project/root
656    //   output root: /project/out
657    //   chunk root path: /project/out/ssr/chunks
658    //   output_root_to_chunk_root: ../root
659    //
660    // From that we want to return  ../../../root to get from a path in `chunks` to a path in the
661    // project root.
662
663    let chunk_root_path = chunking_context.chunk_root_path().await?;
664    let output_root = chunking_context.output_root().await?;
665    let chunk_to_output_root = chunk_root_path.get_relative_path_to(&output_root);
666    let Some(chunk_to_output_root) = chunk_to_output_root else {
667        bail!(
668            "expected chunk_root_path: {chunk_root_path} to be inside of output_root: \
669             {output_root}",
670            chunk_root_path = chunk_root_path.value_to_string().await?,
671            output_root = output_root.value_to_string().await?
672        );
673    };
674    let output_root_to_chunk_root_path = chunking_context.output_root_to_root_path().await?;
675
676    // Note we cannot use `normalize_path` here since it rejects paths that start with `../`
677    Ok(Vc::cell(
678        format!(
679            "{}/{}",
680            chunk_to_output_root, output_root_to_chunk_root_path
681        )
682        .into(),
683    ))
684}
685
686#[turbo_tasks::function]
687fn root_chunk_group_assets(
688    chunking_context: Vc<Box<dyn ChunkingContext>>,
689    ident: Vc<AssetIdent>,
690    chunk_group: ChunkGroup,
691    module_graph: Vc<ModuleGraph>,
692) -> Vc<OutputAssetsWithReferenced> {
693    chunking_context
694        .root_chunk_group(ident, chunk_group, module_graph)
695        .output_assets_with_referenced()
696}
697
698#[turbo_tasks::function]
699fn evaluated_chunk_group_assets(
700    chunking_context: Vc<Box<dyn ChunkingContext>>,
701    ident: Vc<AssetIdent>,
702    chunk_group: ChunkGroup,
703    module_graph: Vc<ModuleGraph>,
704    availability_info: AvailabilityInfo,
705) -> Vc<OutputAssetsWithReferenced> {
706    chunking_context
707        .evaluated_chunk_group(ident, chunk_group, module_graph, availability_info)
708        .output_assets_with_referenced()
709}
710
711#[turbo_tasks::function]
712async fn entry_chunk_group_asset(
713    chunking_context: Vc<Box<dyn ChunkingContext>>,
714    path: FileSystemPath,
715    evaluatable_assets: Vc<EvaluatableAssets>,
716    module_graph: Vc<ModuleGraph>,
717    extra_chunks: Vc<OutputAssets>,
718    extra_referenced_assets: Vc<OutputAssets>,
719    availability_info: AvailabilityInfo,
720) -> Result<Vc<Box<dyn OutputAsset>>> {
721    Ok(*chunking_context
722        .entry_chunk_group(
723            path,
724            evaluatable_assets,
725            module_graph,
726            extra_chunks,
727            extra_referenced_assets,
728            availability_info,
729        )
730        .await?
731        .asset)
732}
733
734#[turbo_tasks::function]
735fn chunk_group_assets(
736    chunking_context: Vc<Box<dyn ChunkingContext>>,
737    ident: Vc<AssetIdent>,
738    chunk_group: ChunkGroup,
739    module_graph: Vc<ModuleGraph>,
740    availability_info: AvailabilityInfo,
741) -> Vc<OutputAssetsWithReferenced> {
742    chunking_context
743        .chunk_group(ident, chunk_group, module_graph, availability_info)
744        .output_assets_with_referenced()
745}