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    environment::Environment,
7};
8
9use crate::{RuntimeType, asset_context::get_runtime_asset_context, 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    environment: ResolvedVc<Environment>,
15    runtime_type: RuntimeType,
16    generate_source_map: bool,
17) -> Result<Vc<Code>> {
18    let asset_context = get_runtime_asset_context(*environment).resolve().await?;
19
20    let shared_runtime_utils_code = embed_static_code(
21        asset_context,
22        rcstr!("shared/runtime/runtime-utils.ts"),
23        generate_source_map,
24    );
25    let shared_base_external_utils_code = embed_static_code(
26        asset_context,
27        rcstr!("shared-node/base-externals-utils.ts"),
28        generate_source_map,
29    );
30    let shared_node_external_utils_code = embed_static_code(
31        asset_context,
32        rcstr!("shared-node/node-externals-utils.ts"),
33        generate_source_map,
34    );
35    let shared_node_wasm_utils_code = embed_static_code(
36        asset_context,
37        rcstr!("shared-node/node-wasm-utils.ts"),
38        generate_source_map,
39    );
40
41    // Runtime base is shared between production and development
42    let runtime_base_code = embed_static_code(
43        asset_context,
44        rcstr!("nodejs/runtime/runtime-base.ts"),
45        generate_source_map,
46    );
47
48    let mut code = CodeBuilder::default();
49    code.push_code(&*shared_runtime_utils_code.await?);
50    code.push_code(&*shared_base_external_utils_code.await?);
51    code.push_code(&*shared_node_external_utils_code.await?);
52    code.push_code(&*shared_node_wasm_utils_code.await?);
53    code.push_code(&*runtime_base_code.await?);
54
55    match runtime_type {
56        RuntimeType::Production => {
57            code.push_code(
58                &*embed_static_code(
59                    asset_context,
60                    rcstr!("nodejs/runtime/build-base.ts"),
61                    generate_source_map,
62                )
63                .await?,
64            );
65        }
66        RuntimeType::Development => {
67            // Include shared HMR runtime (includes instantiateModuleShared, etc.)
68            code.push_code(
69                &*embed_static_code(
70                    asset_context,
71                    rcstr!("shared/runtime/hmr-runtime.ts"),
72                    generate_source_map,
73                )
74                .await?,
75            );
76
77            // Include Node.js-specific dev runtime
78            code.push_code(
79                &*embed_static_code(
80                    asset_context,
81                    rcstr!("nodejs/runtime/dev-base.ts"),
82                    generate_source_map,
83                )
84                .await?,
85            );
86
87            // Include Node.js HMR client (standalone, doesn't use shared ESM client)
88            code.push_code(
89                &*embed_static_code(
90                    asset_context,
91                    rcstr!("nodejs/dev/hmr-client.ts"),
92                    generate_source_map,
93                )
94                .await?,
95            );
96
97            // Include dev-nodejs (HMR initialization and __turbopack_server_hmr_apply__)
98            code.push_code(
99                &*embed_static_code(
100                    asset_context,
101                    rcstr!("nodejs/dev/dev-nodejs.ts"),
102                    generate_source_map,
103                )
104                .await?,
105            );
106        }
107        #[cfg(feature = "test")]
108        RuntimeType::Dummy => {
109            panic!("Dummy runtime is not supported in Node.js runtime")
110        }
111    }
112
113    Ok(Code::cell(code.build()))
114}