turbopack_ecmascript/
static_code.rs

1use anyhow::{Result, bail};
2use turbo_tasks::{ResolvedVc, Vc};
3use turbo_tasks_fs::FileSystemPath;
4use turbopack_core::{
5    code_builder::{Code, CodeBuilder},
6    context::AssetContext,
7    file_source::FileSource,
8    reference_type::ReferenceType,
9};
10
11use crate::EcmascriptAnalyzable;
12
13/// Static ECMAScript file code, to be used as part of some code.
14///
15/// Useful to transform partial runtime code files, which get concatenated into
16/// the final runtime code, while keeping source map information.
17#[turbo_tasks::value]
18pub struct StaticEcmascriptCode {
19    asset_context: ResolvedVc<Box<dyn AssetContext>>,
20    asset: ResolvedVc<Box<dyn EcmascriptAnalyzable>>,
21    generate_source_map: bool,
22}
23
24#[turbo_tasks::value_impl]
25impl StaticEcmascriptCode {
26    /// Creates a new [`Vc<StaticEcmascriptCode>`].
27    #[turbo_tasks::function]
28    pub async fn new(
29        asset_context: ResolvedVc<Box<dyn AssetContext>>,
30        asset_path: FileSystemPath,
31        generate_source_map: bool,
32    ) -> Result<Vc<Self>> {
33        let module = asset_context
34            .process(
35                Vc::upcast(FileSource::new(asset_path.clone())),
36                ReferenceType::Runtime,
37            )
38            .module()
39            .to_resolved()
40            .await?;
41        let Some(asset) = ResolvedVc::try_sidecast::<Box<dyn EcmascriptAnalyzable>>(module) else {
42            bail!("asset is not an Ecmascript module")
43        };
44        Ok(Self::cell(StaticEcmascriptCode {
45            asset_context,
46            asset,
47            generate_source_map,
48        }))
49    }
50
51    /// Computes the contents of the asset and pushes it to
52    /// the code builder, including the source map if available.
53    #[turbo_tasks::function]
54    pub async fn code(&self) -> Result<Vc<Code>> {
55        let runtime_base_content = self
56            .asset
57            .module_content_without_analysis(self.generate_source_map)
58            .await?;
59        let mut code = CodeBuilder::default();
60        code.push_source(
61            &runtime_base_content.inner_code,
62            runtime_base_content.source_map.clone(),
63        );
64        Ok(Code::cell(code.build()))
65    }
66}