turbopack_static/
ecma.rs

1use anyhow::Result;
2use turbo_rcstr::rcstr;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbopack_core::{
5    asset::{Asset, AssetContent},
6    chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext},
7    ident::AssetIdent,
8    module::Module,
9    module_graph::ModuleGraph,
10    output::{OutputAsset, OutputAssets},
11    source::Source,
12};
13use turbopack_ecmascript::{
14    chunk::{
15        EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable,
16        EcmascriptChunkType, EcmascriptExports,
17    },
18    runtime_functions::TURBOPACK_EXPORT_VALUE,
19    utils::StringifyJs,
20};
21
22use crate::output_asset::StaticOutputAsset;
23
24#[turbo_tasks::value]
25#[derive(Clone)]
26pub struct StaticUrlJsModule {
27    pub source: ResolvedVc<Box<dyn Source>>,
28}
29
30#[turbo_tasks::value_impl]
31impl StaticUrlJsModule {
32    #[turbo_tasks::function]
33    pub fn new(source: ResolvedVc<Box<dyn Source>>) -> Vc<Self> {
34        Self::cell(StaticUrlJsModule { source })
35    }
36
37    #[turbo_tasks::function]
38    fn static_output_asset(
39        &self,
40        chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
41    ) -> Vc<StaticOutputAsset> {
42        StaticOutputAsset::new(*chunking_context, *self.source)
43    }
44}
45
46#[turbo_tasks::value_impl]
47impl Module for StaticUrlJsModule {
48    #[turbo_tasks::function]
49    fn ident(&self) -> Vc<AssetIdent> {
50        self.source
51            .ident()
52            .with_modifier(rcstr!("static in ecmascript"))
53    }
54}
55
56#[turbo_tasks::value_impl]
57impl Asset for StaticUrlJsModule {
58    #[turbo_tasks::function]
59    fn content(&self) -> Vc<AssetContent> {
60        self.source.content()
61    }
62}
63
64#[turbo_tasks::value_impl]
65impl ChunkableModule for StaticUrlJsModule {
66    #[turbo_tasks::function]
67    async fn as_chunk_item(
68        self: ResolvedVc<Self>,
69        _module_graph: Vc<ModuleGraph>,
70        chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
71    ) -> Result<Vc<Box<dyn turbopack_core::chunk::ChunkItem>>> {
72        Ok(Vc::upcast(StaticUrlJsChunkItem::cell(
73            StaticUrlJsChunkItem {
74                module: self,
75                chunking_context,
76                static_asset: self
77                    .static_output_asset(*ResolvedVc::upcast(chunking_context))
78                    .to_resolved()
79                    .await?,
80            },
81        )))
82    }
83}
84
85#[turbo_tasks::value_impl]
86impl EcmascriptChunkPlaceable for StaticUrlJsModule {
87    #[turbo_tasks::function]
88    fn get_exports(&self) -> Vc<EcmascriptExports> {
89        EcmascriptExports::Value.into()
90    }
91}
92
93#[turbo_tasks::value]
94struct StaticUrlJsChunkItem {
95    module: ResolvedVc<StaticUrlJsModule>,
96    chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
97    static_asset: ResolvedVc<StaticOutputAsset>,
98}
99
100#[turbo_tasks::value_impl]
101impl ChunkItem for StaticUrlJsChunkItem {
102    #[turbo_tasks::function]
103    fn asset_ident(&self) -> Vc<AssetIdent> {
104        self.module.ident()
105    }
106
107    #[turbo_tasks::function]
108    fn references(&self) -> Vc<OutputAssets> {
109        Vc::cell(vec![ResolvedVc::upcast(self.static_asset)])
110    }
111
112    #[turbo_tasks::function]
113    fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
114        *ResolvedVc::upcast(self.chunking_context)
115    }
116
117    #[turbo_tasks::function]
118    async fn ty(&self) -> Result<Vc<Box<dyn ChunkType>>> {
119        Ok(Vc::upcast(
120            Vc::<EcmascriptChunkType>::default().resolve().await?,
121        ))
122    }
123
124    #[turbo_tasks::function]
125    fn module(&self) -> Vc<Box<dyn Module>> {
126        *ResolvedVc::upcast(self.module)
127    }
128}
129
130#[turbo_tasks::value_impl]
131impl EcmascriptChunkItem for StaticUrlJsChunkItem {
132    #[turbo_tasks::function]
133    async fn content(&self) -> Result<Vc<EcmascriptChunkItemContent>> {
134        Ok(EcmascriptChunkItemContent {
135            inner_code: format!(
136                "{TURBOPACK_EXPORT_VALUE}({path});",
137                path = StringifyJs(
138                    &self
139                        .chunking_context
140                        .asset_url(self.static_asset.path().await?.clone_value())
141                        .await?
142                )
143            )
144            .into(),
145            ..Default::default()
146        }
147        .into())
148    }
149}
150
151pub fn register() {
152    turbo_tasks::register();
153    turbo_tasks_fs::register();
154    turbopack_core::register();
155    turbopack_ecmascript::register();
156    include!(concat!(env!("OUT_DIR"), "/register.rs"));
157}