turbopack_browser/ecmascript/evaluate/
single_entry_chunk.rs1use anyhow::Result;
2use turbo_tasks::{ResolvedVc, ValueToString, Vc};
3use turbo_tasks_fs::{File, FileContent, FileSystemPath};
4use turbopack_core::{
5 asset::{Asset, AssetContent},
6 chunk::{Chunk, ChunkingContext, EvaluatableAssets},
7 code_builder::{Code, CodeBuilder},
8 module_graph::ModuleGraph,
9 output::{
10 OutputAsset, OutputAssets, OutputAssetsReference, OutputAssetsReferences,
11 OutputAssetsWithReferenced,
12 },
13 source_map::{GenerateSourceMap, SourceMapAsset},
14};
15use turbopack_ecmascript::chunk::EcmascriptChunk;
16
17use crate::{
18 BrowserChunkingContext,
19 ecmascript::{chunk::EcmascriptBrowserChunk, evaluate::chunk::EcmascriptBrowserEvaluateChunk},
20};
21
22#[turbo_tasks::value(shared)]
28#[derive(ValueToString)]
29#[value_to_string("Ecmascript Browser Single Entry Chunk")]
30pub struct EcmascriptBrowserSingleEntryChunk {
31 chunking_context: ResolvedVc<BrowserChunkingContext>,
32 path: FileSystemPath,
33 chunk: ResolvedVc<EcmascriptChunk>,
34 evaluatable_assets: ResolvedVc<EvaluatableAssets>,
35 referenced_output_assets: ResolvedVc<OutputAssets>,
36 references: ResolvedVc<OutputAssetsReferences>,
37 module_graph: ResolvedVc<ModuleGraph>,
38}
39
40#[turbo_tasks::value_impl]
41impl EcmascriptBrowserSingleEntryChunk {
42 #[turbo_tasks::function]
43 pub fn new(
44 chunking_context: ResolvedVc<BrowserChunkingContext>,
45 path: FileSystemPath,
46 chunk: ResolvedVc<EcmascriptChunk>,
47 evaluatable_assets: ResolvedVc<EvaluatableAssets>,
48 referenced_output_assets: ResolvedVc<OutputAssets>,
49 references: ResolvedVc<OutputAssetsReferences>,
50 module_graph: ResolvedVc<ModuleGraph>,
51 ) -> Vc<Self> {
52 EcmascriptBrowserSingleEntryChunk {
53 chunking_context,
54 path,
55 chunk,
56 evaluatable_assets,
57 referenced_output_assets,
58 references,
59 module_graph,
60 }
61 .cell()
62 }
63
64 #[turbo_tasks::function]
65 async fn code(self: Vc<Self>) -> Result<Vc<Code>> {
66 let this = self.await?;
67
68 let source_maps = *this
69 .chunking_context
70 .reference_chunk_source_maps(Vc::upcast(self))
71 .await?;
72 let mut code = CodeBuilder::new(
73 source_maps,
74 *this.chunking_context.debug_ids_enabled().await?,
75 );
76
77 let module_chunk = EcmascriptBrowserChunk::new(*this.chunking_context, *this.chunk);
78 code.push_code(&*module_chunk.own_content().code().await?);
79
80 let evaluate_chunk = EcmascriptBrowserEvaluateChunk::new(
81 *this.chunking_context,
82 this.chunk.ident(),
83 OutputAssets::empty(),
84 *this.evaluatable_assets,
85 *this.module_graph,
86 );
87 code.push_code(&*evaluate_chunk.code().await?);
88
89 if *this.chunking_context.shared_runtime().await? {
91 let runtime_chunk = this
92 .chunking_context
93 .generate_runtime_chunk(*this.module_graph)
94 .await?;
95 code.push_code(&*runtime_chunk.code().await?);
96 }
97
98 Ok(Code::cell(code.build()))
99 }
100
101 #[turbo_tasks::function]
102 async fn source_map(self: Vc<Self>) -> Result<Vc<SourceMapAsset>> {
103 let this = self.await?;
104 Ok(SourceMapAsset::new_fixed(
105 this.path.clone(),
106 Vc::upcast(self),
107 ))
108 }
109}
110
111#[turbo_tasks::value_impl]
112impl OutputAssetsReference for EcmascriptBrowserSingleEntryChunk {
113 #[turbo_tasks::function]
114 async fn references(self: Vc<Self>) -> Result<Vc<OutputAssetsWithReferenced>> {
115 let this = self.await?;
116 let mut assets = Vec::new();
117
118 if *this
119 .chunking_context
120 .reference_chunk_source_maps(Vc::upcast(self))
121 .await?
122 {
123 assets.push(ResolvedVc::upcast(self.source_map().to_resolved().await?));
124 }
125
126 Ok(OutputAssetsWithReferenced {
127 assets: ResolvedVc::cell(assets),
128 referenced_assets: this.referenced_output_assets,
129 references: this.references,
130 }
131 .cell())
132 }
133}
134
135#[turbo_tasks::value_impl]
136impl OutputAsset for EcmascriptBrowserSingleEntryChunk {
137 #[turbo_tasks::function]
138 fn path(&self) -> Vc<FileSystemPath> {
139 self.path.clone().cell()
140 }
141}
142
143#[turbo_tasks::value_impl]
144impl Asset for EcmascriptBrowserSingleEntryChunk {
145 #[turbo_tasks::function]
146 async fn content(self: Vc<Self>) -> Result<Vc<AssetContent>> {
147 Ok(AssetContent::file(
148 FileContent::Content(File::from(
149 self.code()
150 .to_rope_with_magic_comments(|| self.source_map())
151 .await?,
152 ))
153 .cell(),
154 ))
155 }
156}
157
158#[turbo_tasks::value_impl]
159impl GenerateSourceMap for EcmascriptBrowserSingleEntryChunk {
160 #[turbo_tasks::function]
161 fn generate_source_map(self: Vc<Self>) -> Vc<FileContent> {
162 self.code().generate_source_map()
163 }
164}