Skip to main content

turbopack_ecmascript_runtime/
nodejs_runtime.rs

1use anyhow::Result;
2use turbo_rcstr::rcstr;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbopack_core::{
5    code_builder::{Code, CodeBuilder},
6    context::AssetContext,
7};
8
9use crate::{RuntimeType, embed_js::embed_static_code};
10
11/// Returns the code for the Node.js ECMAScript runtime.
12#[turbo_tasks::function]
13pub async fn get_nodejs_runtime_code(
14    asset_context: ResolvedVc<Box<dyn AssetContext>>,
15    runtime_type: RuntimeType,
16    has_async_modules: bool,
17    generate_source_map: bool,
18) -> Result<Vc<Code>> {
19    let asset_context = *asset_context;
20
21    let shared_runtime_utils_code = embed_static_code(
22        asset_context,
23        rcstr!("shared/runtime/runtime-utils.ts"),
24        generate_source_map,
25    );
26    let shared_base_external_utils_code = embed_static_code(
27        asset_context,
28        rcstr!("shared-node/base-externals-utils.ts"),
29        generate_source_map,
30    );
31    let shared_node_external_utils_code = embed_static_code(
32        asset_context,
33        rcstr!("shared-node/node-externals-utils.ts"),
34        generate_source_map,
35    );
36    // Runtime base is shared between production and development
37    let runtime_base_code = embed_static_code(
38        asset_context,
39        rcstr!("nodejs/runtime/runtime-base.ts"),
40        generate_source_map,
41    );
42
43    let mut code = CodeBuilder::default();
44    code.push_code(&*shared_runtime_utils_code.await?);
45    // Only include the async-module (top-level await) machinery when the app uses it.
46    if has_async_modules {
47        code.push_code(
48            &*embed_static_code(
49                asset_context,
50                rcstr!("shared/runtime/async-module.ts"),
51                generate_source_map,
52            )
53            .await?,
54        );
55    }
56    code.push_code(&*shared_base_external_utils_code.await?);
57    code.push_code(&*shared_node_external_utils_code.await?);
58    code.push_code(&*runtime_base_code.await?);
59
60    match runtime_type {
61        RuntimeType::Production => {
62            code.push_code(
63                &*embed_static_code(
64                    asset_context,
65                    rcstr!("nodejs/runtime/build-base.ts"),
66                    generate_source_map,
67                )
68                .await?,
69            );
70        }
71        RuntimeType::Development => {
72            // Include shared HMR runtime (includes instantiateModuleShared, etc.)
73            code.push_code(
74                &*embed_static_code(
75                    asset_context,
76                    rcstr!("shared/runtime/hmr-runtime.ts"),
77                    generate_source_map,
78                )
79                .await?,
80            );
81
82            // Include Node.js-specific dev runtime
83            code.push_code(
84                &*embed_static_code(
85                    asset_context,
86                    rcstr!("nodejs/runtime/dev-base.ts"),
87                    generate_source_map,
88                )
89                .await?,
90            );
91
92            // Include Node.js HMR client (standalone, doesn't use shared ESM client)
93            code.push_code(
94                &*embed_static_code(
95                    asset_context,
96                    rcstr!("nodejs/dev/hmr-client.ts"),
97                    generate_source_map,
98                )
99                .await?,
100            );
101
102            // Include dev-nodejs (HMR initialization and __turbopack_server_hmr_apply__)
103            code.push_code(
104                &*embed_static_code(
105                    asset_context,
106                    rcstr!("nodejs/dev/dev-nodejs.ts"),
107                    generate_source_map,
108                )
109                .await?,
110            );
111        }
112        #[cfg(feature = "test")]
113        RuntimeType::Dummy => {
114            panic!("Dummy runtime is not supported in Node.js runtime")
115        }
116    }
117
118    Ok(Code::cell(code.build()))
119}