turbopack/
evaluate_context.rs1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::Vc;
4use turbo_tasks_env::ProcessEnv;
5use turbo_tasks_fs::FileSystem;
6use turbopack_core::{
7 compile_time_defines,
8 compile_time_info::CompileTimeInfo,
9 condition::ContextCondition,
10 context::AssetContext,
11 environment::{Environment, ExecutionEnvironment, NodeJsEnvironment},
12 ident::Layer,
13 resolve::options::{ImportMap, ImportMapping},
14};
15use turbopack_ecmascript::TreeShakingMode;
16use turbopack_node::execution_context::ExecutionContext;
17use turbopack_resolve::resolve_options_context::ResolveOptionsContext;
18
19use crate::{
20 ModuleAssetContext,
21 module_options::{EcmascriptOptionsContext, ModuleOptionsContext, TypescriptTransformOptions},
22 transition::TransitionOptions,
23};
24
25#[turbo_tasks::function]
26pub fn node_build_environment() -> Vc<Environment> {
27 Environment::new(ExecutionEnvironment::NodeJsBuildTime(
28 NodeJsEnvironment::default().resolved_cell(),
29 ))
30}
31
32#[turbo_tasks::function]
33pub async fn node_evaluate_asset_context(
34 execution_context: Vc<ExecutionContext>,
35 import_map: Option<Vc<ImportMap>>,
36 transitions: Option<Vc<TransitionOptions>>,
37 layer: Layer,
38 ignore_dynamic_requests: bool,
39) -> Result<Vc<Box<dyn AssetContext>>> {
40 let mut import_map = if let Some(import_map) = import_map {
41 import_map.owned().await?
42 } else {
43 ImportMap::empty()
44 };
45 import_map.insert_wildcard_alias(
46 "@vercel/turbopack-node/",
47 ImportMapping::PrimaryAlternative(
48 rcstr!("./*"),
49 Some(
50 turbopack_node::embed_js::embed_fs()
51 .root()
52 .await?
53 .clone_value(),
54 ),
55 )
56 .resolved_cell(),
57 );
58 let import_map = import_map.resolved_cell();
59 let node_env: RcStr =
60 if let Some(node_env) = &*execution_context.env().read(rcstr!("NODE_ENV")).await? {
61 node_env.clone()
62 } else {
63 rcstr!("development")
64 };
65
66 let resolve_options_context = ResolveOptionsContext {
69 enable_node_modules: Some(
70 execution_context
71 .project_path()
72 .await?
73 .root()
74 .await?
75 .clone_value(),
76 ),
77 enable_node_externals: true,
78 enable_node_native_modules: true,
79 custom_conditions: vec![node_env.clone(), rcstr!("node")],
80 ..Default::default()
81 };
82 let resolve_options_context = ResolveOptionsContext {
84 enable_typescript: true,
85 import_map: Some(import_map),
86 rules: vec![(
87 ContextCondition::InDirectory("node_modules".to_string()),
88 resolve_options_context.clone().resolved_cell(),
89 )],
90 ..resolve_options_context
91 }
92 .cell();
93
94 Ok(Vc::upcast(ModuleAssetContext::new(
95 transitions.unwrap_or_default(),
96 CompileTimeInfo::builder(node_build_environment().to_resolved().await?)
97 .defines(
98 compile_time_defines!(
99 process.turbopack = true,
100 process.env.NODE_ENV = node_env.into_owned(),
101 process.env.TURBOPACK = true
102 )
103 .resolved_cell(),
104 )
105 .cell()
106 .await?,
107 ModuleOptionsContext {
108 tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly),
109 ecmascript: EcmascriptOptionsContext {
110 enable_typescript_transform: Some(
111 TypescriptTransformOptions::default().resolved_cell(),
112 ),
113 ignore_dynamic_requests,
114 ..Default::default()
115 },
116 ..Default::default()
117 }
118 .cell(),
119 resolve_options_context,
120 layer,
121 )))
122}