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, module_graph::ModuleGraph};
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        _module_graph: Vc<ModuleGraph>,
43        _chunking_context: Vc<Box<dyn ChunkingContext>>,
44    ) -> Result<CodeGeneration> {
45        let visitor = match self.ty {
46            DynamicExpressionType::Normal => {
47                create_visitor!(self.path, visit_mut_expr(expr: &mut Expr) {
48                    *expr = quote!("(() => { const e = new Error(\"Cannot find module as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })()" as Expr);
49                })
50            }
51            DynamicExpressionType::Promise => {
52                create_visitor!(self.path, visit_mut_expr(expr: &mut Expr) {
53                    *expr = quote!("Promise.resolve().then(() => { const e = new Error(\"Cannot find module as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })" as Expr);
54                })
55            }
56        };
57
58        Ok(CodeGeneration::visitors(vec![visitor]))
59    }
60}
61
62impl From<DynamicExpression> for CodeGen {
63    fn from(val: DynamicExpression) -> Self {
64        CodeGen::DynamicExpression(val)
65    }
66}