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: ResolvedVc<Box<dyn EcmascriptAnalyzable>>,
20    generate_source_map: bool,
21}
22
23#[turbo_tasks::value_impl]
24impl StaticEcmascriptCode {
25    /// Creates a new [`Vc<StaticEcmascriptCode>`].
26    #[turbo_tasks::function]
27    pub async fn new(
28        asset_context: ResolvedVc<Box<dyn AssetContext>>,
29        asset_path: FileSystemPath,
30        generate_source_map: bool,
31    ) -> Result<Vc<Self>> {
32        let module = asset_context
33            .process(
34                Vc::upcast(FileSource::new(asset_path.clone())),
35                ReferenceType::Runtime,
36            )
37            .module()
38            .to_resolved()
39            .await?;
40        let Some(asset) = ResolvedVc::try_sidecast::<Box<dyn EcmascriptAnalyzable>>(module) else {
41            bail!("asset is not an Ecmascript module")
42        };
43        Ok(Self::cell(StaticEcmascriptCode {
44            asset,
45            generate_source_map,
46        }))
47    }
48
49    /// Computes the contents of the asset and pushes it to
50    /// the code builder, including the source map if available.
51    #[turbo_tasks::function]
52    pub async fn code(&self) -> Result<Vc<Code>> {
53        let runtime_base_content = self
54            .asset
55            .module_content_without_analysis(self.generate_source_map)
56            .await?;
57        let mut code = CodeBuilder::default();
58        code.push_source(
59            &runtime_base_content.inner_code,
60            runtime_base_content.source_map.clone(),
61        );
62        Ok(Code::cell(code.build()))
63    }
64}