turbopack_ecmascript/references/
dynamic_expression.rs1use 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}