Skip to content

Commit 5172147

Browse files
committed
fix: support rspack runtime mode context
1 parent 8dbcc04 commit 5172147

47 files changed

Lines changed: 569 additions & 475 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

crates/rspack_binding_api/src/plugins/interceptor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use napi::{
1111
Either, Env, JsValue,
1212
bindgen_prelude::{Buffer, FromNapiValue, Function, JsValuesTupleIntoVec, Promise, ToNapiValue},
1313
};
14-
use rspack_collections::{IdentifierMap, IdentifierSet};
14+
use rspack_collections::{Identifier, IdentifierMap, IdentifierSet};
1515
use rspack_core::{
1616
AfterResolveResult, AssetEmittedInfo, AsyncModulesArtifact, BeforeResolveResult, BindingCell,
1717
BoxModule, ChunkGraph, ChunkUkey, Compilation, CompilationAdditionalTreeRuntimeRequirements,
@@ -1242,7 +1242,7 @@ impl CompilationExecuteModule for CompilationExecuteModuleTap {
12421242
async fn run(
12431243
&self,
12441244
entry: &ModuleIdentifier,
1245-
runtime_modules: &IdentifierSet,
1245+
runtime_modules: &[Identifier],
12461246
code_generation_results: &BindingCell<rspack_core::CodeGenerationResults>,
12471247
id: &ExecuteModuleId,
12481248
) -> rspack_error::Result<()> {

crates/rspack_core/src/artifacts/runtime_proxy_metadata_artifact.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,33 @@ use crate::{ArtifactExt, ChunkUkey, RuntimeGlobals, incremental::IncrementalPass
66

77
#[derive(Debug, Default, Clone)]
88
pub struct RuntimeProxyMetadata {
9+
pub tree_runtime_requirements: RuntimeGlobals,
910
pub module_proxy_requirements: RuntimeGlobals,
1011
pub runtime_module_requirements: RuntimeGlobals,
1112
pub context_setter_fields: RuntimeGlobals,
1213
pub hook_exposed_requirements: RuntimeGlobals,
1314
}
1415

1516
impl RuntimeProxyMetadata {
17+
fn renderable_fields(runtime_globals: RuntimeGlobals) -> RuntimeGlobals {
18+
runtime_globals
19+
.renderable_require_scope()
20+
.difference(RuntimeGlobals::REQUIRE | RuntimeGlobals::REQUIRE_SCOPE)
21+
}
22+
1623
pub fn lexical_fields(&self) -> RuntimeGlobals {
17-
let mut fields = self.runtime_module_requirements;
18-
fields.insert(self.module_proxy_requirements);
19-
fields.insert(self.context_setter_fields);
20-
fields.insert(self.hook_exposed_requirements);
21-
fields
24+
Self::renderable_fields(self.tree_runtime_requirements)
2225
}
2326

2427
pub fn context_fields(&self) -> RuntimeGlobals {
2528
let mut fields = self.module_proxy_requirements;
2629
fields.insert(self.context_setter_fields);
2730
fields.insert(self.hook_exposed_requirements);
28-
fields
31+
Self::renderable_fields(fields)
32+
}
33+
34+
pub fn context_setter_fields(&self) -> RuntimeGlobals {
35+
Self::renderable_fields(self.context_setter_fields)
2936
}
3037
}
3138

crates/rspack_core/src/compilation/build_module_graph/module_executor/execute.rs

Lines changed: 119 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
use std::{collections::VecDeque, iter::once, sync::atomic::AtomicU32};
1+
use std::{collections::VecDeque, fmt::Write, iter::once, sync::atomic::AtomicU32};
22

33
use itertools::Itertools;
44
use rspack_collections::{Identifier, IdentifierSet};
55
use rspack_error::Error;
66
use rspack_paths::ArcPathSet;
7+
use rspack_sources::{RawStringSource, SourceExt};
78
use rustc_hash::{FxHashMap as HashMap, FxHashSet};
89
use tokio::sync::oneshot::Sender;
910

1011
use super::context::{ExecutorTaskContext, ImportModuleMeta};
1112
use crate::{
12-
Chunk, ChunkGraph, ChunkKind, CodeGenerationDataAssetInfo, CodeGenerationDataFilename,
13-
CodeGenerationResult, CompilationAsset, CompilationAssets, EntryOptions, Entrypoint,
13+
Chunk, ChunkGraph, ChunkKind, ChunkUkey, CodeGenerationDataAssetInfo, CodeGenerationDataFilename,
14+
CodeGenerationResult, Compilation, CompilationAsset, CompilationAssets, EntryOptions, Entrypoint,
1415
FactorizeInfo, ModuleCodeGenerationContext, ModuleType, PublicPath, RuntimeSpec, SourceType,
1516
compilation::{
1617
code_generation::code_generation_modules,
@@ -19,6 +20,9 @@ use crate::{
1920
process_chunks_runtime_requirements, process_modules_runtime_requirements,
2021
},
2122
},
23+
property_access,
24+
runtime_globals::{RuntimeVariable, runtime_variable_name},
25+
runtime_mode::RuntimeMode,
2226
utils::task_loop::{Task, TaskResult, TaskType},
2327
};
2428

@@ -35,6 +39,97 @@ pub struct ExecutedRuntimeModule {
3539
static EXECUTE_MODULE_ID: AtomicU32 = AtomicU32::new(0);
3640
pub type ExecuteModuleId = u32;
3741

42+
fn create_execute_runtime_source(
43+
compilation: &Compilation,
44+
chunk_ukey: &ChunkUkey,
45+
runtime_modules: &[Identifier],
46+
) -> Option<(Identifier, CodeGenerationResult)> {
47+
if compilation.options.experiments.runtime_mode != RuntimeMode::Rspack {
48+
return None;
49+
}
50+
51+
let metadata = compilation
52+
.runtime_proxy_metadata_artifact
53+
.get(chunk_ukey)?;
54+
let lexical_fields = metadata.lexical_fields();
55+
let context_fields = metadata.context_fields();
56+
if lexical_fields.is_empty() && context_fields.is_empty() && runtime_modules.is_empty() {
57+
return None;
58+
}
59+
60+
let runtime_context = runtime_variable_name(&RuntimeVariable::Context);
61+
let mut source = String::new();
62+
for (_, runtime_global) in lexical_fields.iter_names() {
63+
let Some(lexical_name) = runtime_global.to_lexical_name() else {
64+
continue;
65+
};
66+
writeln!(source, "var {lexical_name};").expect("write to string should succeed");
67+
}
68+
for runtime_id in runtime_modules {
69+
let runtime_module = compilation
70+
.runtime_modules
71+
.get(runtime_id)
72+
.expect("runtime module should exist");
73+
let runtime_module_source = compilation
74+
.code_generation_results
75+
.get(runtime_id, None)
76+
.get(&SourceType::JavaScript)
77+
.expect("runtime module should have runtime source");
78+
writeln!(source, "// {}", runtime_module.identifier()).expect("write to string should succeed");
79+
if runtime_module.should_isolate() {
80+
if compilation
81+
.options
82+
.output
83+
.environment
84+
.supports_arrow_function()
85+
{
86+
writeln!(source, "(() => {{").expect("write to string should succeed");
87+
} else {
88+
writeln!(source, "!function() {{").expect("write to string should succeed");
89+
}
90+
}
91+
writeln!(
92+
source,
93+
"{}",
94+
runtime_module_source.source().into_string_lossy()
95+
)
96+
.expect("write to string should succeed");
97+
if runtime_module.should_isolate() {
98+
if compilation
99+
.options
100+
.output
101+
.environment
102+
.supports_arrow_function()
103+
{
104+
writeln!(source, "}})();").expect("write to string should succeed");
105+
} else {
106+
writeln!(source, "}}();").expect("write to string should succeed");
107+
}
108+
}
109+
}
110+
for (_, runtime_global) in context_fields.iter_names() {
111+
let (Some(property_name), Some(lexical_name)) = (
112+
runtime_global.property_name(),
113+
runtime_global.to_lexical_name(),
114+
) else {
115+
continue;
116+
};
117+
writeln!(
118+
source,
119+
"if (typeof {lexical_name} !== \"undefined\") {runtime_context}{} = {lexical_name};",
120+
property_access([property_name], 0)
121+
)
122+
.expect("write to string should succeed");
123+
}
124+
125+
(!source.is_empty()).then(|| {
126+
(
127+
Identifier::from("webpack/runtime/execute_module_runtime"),
128+
CodeGenerationResult::default().with_javascript(RawStringSource::from(source).boxed()),
129+
)
130+
})
131+
}
132+
38133
#[derive(Debug, Default)]
39134
pub struct ExecuteModuleResult {
40135
pub error: Option<String>,
@@ -309,9 +404,9 @@ impl Task<ExecutorTaskContext> for ExecuteTask {
309404
let runtime_modules = compilation
310405
.build_chunk_graph_artifact
311406
.chunk_graph
312-
.get_chunk_runtime_modules_iterable(&chunk_ukey)
313-
.copied()
314-
.collect::<IdentifierSet>();
407+
.get_chunk_runtime_modules_in_order(&chunk_ukey, &compilation)
408+
.map(|(identifier, _)| *identifier)
409+
.collect_vec();
315410

316411
tracing::debug!(
317412
"runtime modules: {:?}",
@@ -325,9 +420,7 @@ impl Task<ExecutorTaskContext> for ExecuteTask {
325420
.get(runtime_id)
326421
.expect("runtime module exist");
327422

328-
let mut runtime_template = compilation
329-
.runtime_template
330-
.create_runtime_module_code_template();
423+
let mut runtime_template = compilation.runtime_template.create_module_code_template();
331424
let mut code_generation_context = ModuleCodeGenerationContext {
332425
compilation: &compilation,
333426
runtime: None,
@@ -355,12 +448,28 @@ impl Task<ExecutorTaskContext> for ExecuteTask {
355448
.insert(runtime_module.identifier());
356449
}
357450

451+
let runtime_modules_to_execute = if let Some((runtime_identifier, runtime_result)) =
452+
create_execute_runtime_source(&compilation, &chunk_ukey, &runtime_modules)
453+
{
454+
compilation.code_generation_results.insert(
455+
runtime_identifier,
456+
runtime_result,
457+
std::iter::once(runtime.clone()),
458+
);
459+
compilation
460+
.code_generated_modules
461+
.insert(runtime_identifier);
462+
vec![runtime_identifier]
463+
} else {
464+
runtime_modules.clone()
465+
};
466+
358467
let exports = main_compilation_plugin_driver
359468
.compilation_hooks
360469
.execute_module
361470
.call(
362471
&entry_module_identifier,
363-
&runtime_modules,
472+
&runtime_modules_to_execute,
364473
&compilation.code_generation_results,
365474
&id,
366475
)

crates/rspack_core/src/compilation/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rspack_cacheable::{
4545
cacheable,
4646
with::{AsOption, AsPreset, AsVec},
4747
};
48-
use rspack_collections::{IdentifierDashMap, IdentifierMap, IdentifierSet};
48+
use rspack_collections::{Identifier, IdentifierDashMap, IdentifierMap, IdentifierSet};
4949
use rspack_error::{Diagnostic, Result, ToStringResultToRspackResultExt};
5050
use rspack_fs::{IntermediateFileSystem, ReadableFileSystem, WritableFileSystem};
5151
use rspack_hash::{RspackHash, RspackHashDigest};
@@ -102,7 +102,7 @@ define_hook!(CompilationRevokedModules: Series(compilation: &Compilation, revoke
102102
define_hook!(CompilationStillValidModule: Series(compiler_id: CompilerId, compilation_id: CompilationId, module: &mut BoxModule));
103103
define_hook!(CompilationSucceedModule: Series(compiler_id: CompilerId, compilation_id: CompilationId, module: &mut BoxModule),tracing=false);
104104
define_hook!(CompilationExecuteModule:
105-
Series(module: &ModuleIdentifier, runtime_modules: &IdentifierSet, code_generation_results: &BindingCell<CodeGenerationResults>, execute_module_id: &ExecuteModuleId));
105+
Series(module: &ModuleIdentifier, runtime_modules: &[Identifier], code_generation_results: &BindingCell<CodeGenerationResults>, execute_module_id: &ExecuteModuleId));
106106
define_hook!(CompilationFinishModules: Series(compilation: &Compilation, async_modules_artifact: &mut AsyncModulesArtifact, exports_info_artifact: &mut ExportsInfoArtifact, side_effects_state_artifact: &mut SideEffectsStateArtifact));
107107
define_hook!(CompilationSeal: Series(compilation: &Compilation, diagnostics: &mut Vec<Diagnostic>));
108108
define_hook!(CompilationDependencyReferencedExports: Sync(

crates/rspack_core/src/compilation/runtime_requirements/mod.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ pub async fn process_chunks_runtime_requirements(
393393
})
394394
.await?;
395395

396+
if compilation.options.experiments.runtime_mode == ExperimentRuntimeMode::Rspack {
397+
set = set.with_require_scope();
398+
}
399+
396400
for module in runtime_modules_to_add {
397401
compilation.add_runtime_module(&chunk_ukey, module)?;
398402
}
@@ -478,6 +482,10 @@ pub async fn process_chunks_runtime_requirements(
478482
}
479483
}
480484

485+
if compilation.options.experiments.runtime_mode == ExperimentRuntimeMode::Rspack {
486+
all_runtime_requirements = all_runtime_requirements.with_require_scope();
487+
}
488+
481489
ChunkGraph::set_tree_runtime_requirements(compilation, entry_ukey, all_runtime_requirements);
482490
for (chunk_ukey, module) in runtime_modules_to_add {
483491
compilation.add_runtime_module(&chunk_ukey, module)?;
@@ -532,6 +540,14 @@ pub async fn process_chunks_runtime_requirements(
532540
.build_chunk_graph_artifact
533541
.chunk_by_ukey
534542
.expect_get(chunk_ukey);
543+
if let Some(chunk_runtime_requirements) = compilation
544+
.cgc_runtime_requirements_artifact
545+
.get(chunk_ukey)
546+
{
547+
metadata
548+
.hook_exposed_requirements
549+
.insert(*chunk_runtime_requirements);
550+
}
535551
for mid in compilation
536552
.build_chunk_graph_artifact
537553
.chunk_graph
@@ -542,7 +558,7 @@ pub async fn process_chunks_runtime_requirements(
542558
{
543559
metadata
544560
.module_proxy_requirements
545-
.insert(runtime_requirements.renderable_require_scope());
561+
.insert(*runtime_requirements);
546562
}
547563
if compilation
548564
.get_module_graph()
@@ -554,11 +570,9 @@ pub async fn process_chunks_runtime_requirements(
554570
.data
555571
.get::<CodeGenerationRuntimeRequirementsWrite>()
556572
{
557-
metadata.context_setter_fields.insert(
558-
write_requirements
559-
.runtime_requirements
560-
.renderable_require_scope(),
561-
);
573+
metadata
574+
.context_setter_fields
575+
.insert(write_requirements.runtime_requirements);
562576
}
563577
}
564578

@@ -571,24 +585,23 @@ pub async fn process_chunks_runtime_requirements(
571585
.runtime_modules
572586
.get(runtime_module_id)
573587
.expect("should have runtime module");
574-
metadata.runtime_module_requirements.insert(
575-
runtime_module
576-
.additional_runtime_requirements(compilation)
577-
.renderable_require_scope(),
578-
);
588+
let additional_runtime_requirements =
589+
runtime_module.additional_runtime_requirements(compilation);
590+
metadata
591+
.runtime_module_requirements
592+
.insert(additional_runtime_requirements);
593+
metadata
594+
.tree_runtime_requirements
595+
.insert(additional_runtime_requirements);
579596
}
580597
}
581598

582-
metadata.hook_exposed_requirements.insert(
583-
ChunkGraph::get_tree_runtime_requirements(compilation, &entry_ukey)
584-
.renderable_require_scope(),
585-
);
586-
metadata
587-
.context_setter_fields
588-
.insert(metadata.runtime_module_requirements);
589599
metadata
590-
.context_setter_fields
591-
.insert(metadata.hook_exposed_requirements);
600+
.tree_runtime_requirements
601+
.insert(*ChunkGraph::get_tree_runtime_requirements(
602+
compilation,
603+
&entry_ukey,
604+
));
592605
compilation
593606
.runtime_proxy_metadata_artifact
594607
.insert(entry_ukey, metadata);

crates/rspack_core/src/runtime_globals.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@ pub static REQUIRE_SCOPE_GLOBALS: LazyLock<RuntimeGlobals> = LazyLock::new(|| {
314314
runtime_globals.remove(
315315
RuntimeGlobals::MODULE
316316
| RuntimeGlobals::MODULE_ID
317-
| RuntimeGlobals::REQUIRE
318317
| RuntimeGlobals::CHUNK_CALLBACK
319318
| RuntimeGlobals::RETURN_EXPORTS_FROM_RUNTIME
320319
| RuntimeGlobals::MODULE_LOADED
@@ -523,9 +522,15 @@ impl RuntimeGlobals {
523522
}
524523

525524
pub fn renderable_require_scope(self) -> Self {
526-
self
527-
.intersection(*REQUIRE_SCOPE_GLOBALS)
528-
.difference(RuntimeGlobals::REQUIRE_SCOPE)
525+
self.intersection(*REQUIRE_SCOPE_GLOBALS)
526+
}
527+
528+
pub fn with_require_scope(self) -> Self {
529+
if !self.renderable_require_scope().is_empty() {
530+
self | RuntimeGlobals::REQUIRE_SCOPE
531+
} else {
532+
self
533+
}
529534
}
530535

531536
pub fn to_lexical_name(&self) -> Option<&str> {

0 commit comments

Comments
 (0)