turbopack_ecmascript/references/
dynamic_expression.rs

1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use swc_core::quote;
4use turbo_tasks::{NonLocalValue, Vc, debug::ValueDebugFormat, trace::TraceRawVcs};
5use turbopack_core::chunk::ChunkingContext;
6
7use super::AstPath;
8use crate::{
9    code_gen::{CodeGen, CodeGeneration},
10    create_visitor,
11};
12
13#[derive(PartialEq, Eq, TraceRawVcs, Serialize, Deserialize, ValueDebugFormat, NonLocalValue)]
14enum DynamicExpressionType {
15    Promise,
16    Normal,
17}
18
19#[derive(PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, ValueDebugFormat, NonLocalValue)]
20pub struct DynamicExpression {
21    path: AstPath,
22    ty: DynamicExpressionType,
23}
24
25impl DynamicExpression {
26    pub fn new(path: AstPath) -> Self {
27        DynamicExpression {
28            path,
29            ty: DynamicExpressionType::Normal,
30        }
31    }
32
33    pub fn new_promise(path: AstPath) -> Self {
34        DynamicExpression {
35            path,
36            ty: DynamicExpressionType::Promise,
37        }
38    }
39
40    pub async fn code_generation(
41        &self,
42        _chunking_context: Vc<Box<dyn ChunkingContext>>,
43    ) -> Result<CodeGeneration> {
44        let visitor = match self.ty {
45            DynamicExpressionType::Normal => {
46                create_visitor!(self.path, visit_mut_expr, |expr: &mut Expr| {
47                    *expr = quote!(
48                        "(() => { const e = new Error(\"Cannot find module as expression is too \
49                         dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })()"
50                            as Expr
51                    );
52                })
53            }
54            DynamicExpressionType::Promise => {
55                create_visitor!(self.path, visit_mut_expr, |expr: &mut Expr| {
56                    *expr = quote!(
57                        "Promise.resolve().then(() => { const e = new Error(\"Cannot find module \
58                         as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })"
59                            as Expr
60                    );
61                })
62            }
63        };
64
65        Ok(CodeGeneration::visitors(vec![visitor]))
66    }
67}
68
69impl From<DynamicExpression> for CodeGen {
70    fn from(val: DynamicExpression) -> Self {
71        CodeGen::DynamicExpression(val)
72    }
73}