Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1017935
feat(runtime): introduce experimental.runtimeMode
LingyuCoder Jun 10, 2026
3c08905
fix(runtime): limit runtime context compatibility changes
LingyuCoder Jun 11, 2026
e169fb4
fix(runtime): update scan dependency benchmark template
LingyuCoder Jun 11, 2026
fd061d1
fix(runtime): address runtime context review feedback
LingyuCoder Jun 11, 2026
98381f9
fix(runtime): align rspack context global rendering
LingyuCoder Jun 11, 2026
53347ee
esm snapshot
LingyuCoder Jun 11, 2026
6e05d32
fix(runtime): address runtime mode review feedback
LingyuCoder Jun 11, 2026
838a6d4
fix(runtime): address review comments
LingyuCoder Jun 11, 2026
3505f46
fix(runtime): preserve execute runtime helpers
LingyuCoder Jun 11, 2026
e69c3e1
chore: fix js formatting
LingyuCoder Jun 11, 2026
4804e6f
fix(runtime): initialize execute context fields before runtime modules
LingyuCoder Jun 11, 2026
a7e4e50
fix(runtime): expose runtime context requirements
LingyuCoder Jun 12, 2026
9fa902a
fix(runtime): expose generated runtime globals in rspack mode
LingyuCoder Jun 12, 2026
736f0f3
refactor(runtime): split runtime context rendering
LingyuCoder Jun 12, 2026
5081faf
refactor(runtime): simplify runtime module source collection
LingyuCoder Jun 12, 2026
6051212
test(wasm): skip runtime mode tests
LingyuCoder Jun 12, 2026
6a55deb
test: inject runtime mode flag for generated cases
LingyuCoder Jun 12, 2026
9f102bb
test: run runtime mode cases in base project
LingyuCoder Jun 12, 2026
17ede82
fix(runtime): address runtime mode review comments
LingyuCoder Jun 12, 2026
4ce9a07
test(runtime): move chunk id runtime snapshot
LingyuCoder Jun 12, 2026
4aea304
fix(runtime): restore nonce runtime guards
LingyuCoder Jun 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/node_binding/napi-binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2277,6 +2277,7 @@ export interface RawExperiments {
deferImport: boolean
sourceImport: boolean
pureFunctions: boolean
runtimeMode?: "webpack" | "rspack"
}

export interface RawExposeOptions {
Expand Down
6 changes: 5 additions & 1 deletion crates/rspack/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use rspack_core::{
NodeGlobalOption, NodeOption, Optimization, OutputOptions, ParseOption, ParserOptions,
ParserOptionsMap, PathInfo, PublicPath, Resolve, RuleSetCondition, RuleSetLogicalConditions,
SideEffectOption, StatsOptions, TrustedTypes, UsedExportsOption, WasmLoading, WasmLoadingType,
incremental::IncrementalOptions,
incremental::IncrementalOptions, runtime_mode::RuntimeMode,
};
use rspack_error::{Error, Result};
use rspack_fs::{IntermediateFileSystem, ReadableFileSystem, WritableFileSystem};
Expand Down Expand Up @@ -3683,6 +3683,7 @@ pub struct ExperimentsBuilder {
source_import: Option<bool>,
// TODO: lazy compilation
pure_functions: Option<bool>,
runtime_mode: Option<RuntimeMode>,
}

impl From<Experiments> for ExperimentsBuilder {
Expand All @@ -3694,6 +3695,7 @@ impl From<Experiments> for ExperimentsBuilder {
defer_import: Some(value.defer_import),
source_import: Some(value.source_import),
pure_functions: Some(value.pure_functions),
runtime_mode: Some(value.runtime_mode),
}
}
}
Expand All @@ -3707,6 +3709,7 @@ impl From<&mut ExperimentsBuilder> for ExperimentsBuilder {
defer_import: value.defer_import.take(),
source_import: value.source_import.take(),
pure_functions: value.pure_functions.take(),
runtime_mode: value.runtime_mode.take(),
}
}
}
Expand Down Expand Up @@ -3761,6 +3764,7 @@ impl ExperimentsBuilder {
defer_import: d!(self.defer_import, false),
source_import: d!(self.source_import, false),
pure_functions: d!(self.pure_functions, false),
runtime_mode: d!(self.runtime_mode, RuntimeMode::Webpack),
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,7 @@ CompilerOptions {
defer_import: false,
source_import: false,
pure_functions: false,
runtime_mode: Webpack,
},
incremental: IncrementalOptions {
silent: true,
Expand Down
4 changes: 2 additions & 2 deletions crates/rspack_binding_api/src/plugins/interceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use napi::{
Either, Env, JsValue,
bindgen_prelude::{Buffer, FromNapiValue, Function, JsValuesTupleIntoVec, Promise, ToNapiValue},
};
use rspack_collections::{IdentifierMap, IdentifierSet};
use rspack_collections::{Identifier, IdentifierMap, IdentifierSet};
use rspack_core::{
AfterResolveResult, AssetEmittedInfo, AsyncModulesArtifact, BeforeResolveResult, BindingCell,
BoxModule, ChunkGraph, ChunkUkey, CircularModulesInfo, Compilation,
Expand Down Expand Up @@ -1243,7 +1243,7 @@ impl CompilationExecuteModule for CompilationExecuteModuleTap {
async fn run(
&self,
entry: &ModuleIdentifier,
runtime_modules: &IdentifierSet,
runtime_modules: &[Identifier],
code_generation_results: &BindingCell<rspack_core::CodeGenerationResults>,
id: &ExecuteModuleId,
) -> rspack_error::Result<()> {
Expand Down
11 changes: 10 additions & 1 deletion crates/rspack_binding_api/src/raw_options/raw_experiments/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod raw_incremental;

use napi_derive::napi;
pub use raw_incremental::RawIncremental;
use rspack_core::Experiments;
use rspack_core::{Experiments, runtime_mode::RuntimeMode};
use rspack_regex::RspackRegex;

use super::WithFalse;
Expand All @@ -16,15 +16,24 @@ pub struct RawExperiments {
pub defer_import: bool,
pub source_import: bool,
pub pure_functions: bool,
#[napi(ts_type = "\"webpack\" | \"rspack\"")]
pub runtime_mode: Option<String>,
}

impl From<RawExperiments> for Experiments {
fn from(value: RawExperiments) -> Self {
let runtime_mode = if value.runtime_mode.as_deref() == Some("rspack") {
RuntimeMode::Rspack
} else {
RuntimeMode::Webpack
};

Self {
css: value.css.unwrap_or(false),
defer_import: value.defer_import,
source_import: value.source_import,
pure_functions: value.pure_functions,
runtime_mode,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ use crate::{
ArtifactExt, CacheOptions, CodeGenerationJob, CodeGenerationResult, CompilerOptions,
MemoryGCStorage,
incremental::{Incremental, IncrementalPasses},
runtime_mode::RuntimeMode,
};

#[derive(Debug, Default)]
pub struct CodeGenerateCacheArtifact {
storage: Option<MemoryGCStorage<CodeGenerationResult>>,
runtime_mode: RuntimeMode,
}

impl ArtifactExt for CodeGenerateCacheArtifact {
Expand All @@ -30,6 +32,7 @@ impl CodeGenerateCacheArtifact {
CacheOptions::Persistent(_) => Some(MemoryGCStorage::new(1)),
CacheOptions::Disabled => None,
},
runtime_mode: options.experiments.runtime_mode,
}
}

Expand All @@ -53,7 +56,12 @@ impl CodeGenerateCacheArtifact {
return (res, false);
};

let cache_key = Identifier::from(format!("{}|{}", job.module, job.hash.encoded()));
let cache_key = Identifier::from(format!(
"{}|{}|{}",
job.module,
job.hash.encoded(),
self.runtime_mode
));
if let Some(value) = storage.get(&cache_key) {
(Ok(value), true)
} else {
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_core/src/artifacts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod imported_by_defer_modules_artifact;
mod module_graph_cache_artifact;
mod module_ids_artifact;
mod process_runtime_requirements_cache_artifact;
mod runtime_proxy_metadata_artifact;
mod side_effects_do_optimize_artifact;
mod side_effects_state_artifact;

Expand Down Expand Up @@ -102,5 +103,6 @@ pub use imported_by_defer_modules_artifact::ImportedByDeferModulesArtifact;
pub use module_graph_cache_artifact::*;
pub use module_ids_artifact::ModuleIdsArtifact;
pub use process_runtime_requirements_cache_artifact::ProcessRuntimeRequirementsCacheArtifact;
pub use runtime_proxy_metadata_artifact::{RuntimeProxyMetadata, RuntimeProxyMetadataArtifact};
pub use side_effects_do_optimize_artifact::*;
pub use side_effects_state_artifact::*;
146 changes: 146 additions & 0 deletions crates/rspack_core/src/artifacts/runtime_proxy_metadata_artifact.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
use std::{
fmt::Write,
ops::{Deref, DerefMut},
};

use rustc_hash::FxHashMap;

use crate::{
ArtifactExt, ChunkUkey, RuntimeGlobals, incremental::IncrementalPasses, property_access,
};

#[derive(Debug, Default, Clone)]
pub struct RuntimeProxyMetadata {
pub tree_runtime_requirements: RuntimeGlobals,
pub module_proxy_requirements: RuntimeGlobals,
pub bootstrap_proxy_requirements: RuntimeGlobals,
pub runtime_module_requirements: RuntimeGlobals,
pub context_setter_fields: RuntimeGlobals,
pub hook_exposed_requirements: RuntimeGlobals,
}

impl RuntimeProxyMetadata {
fn renderable_fields(runtime_globals: RuntimeGlobals) -> RuntimeGlobals {
runtime_globals
.renderable_require_scope()
.difference(RuntimeGlobals::REQUIRE | RuntimeGlobals::REQUIRE_SCOPE)
}

pub fn lexical_fields(&self) -> RuntimeGlobals {
Self::renderable_fields(self.tree_runtime_requirements)
}

pub fn context_fields(&self) -> RuntimeGlobals {
let mut fields = self.module_proxy_requirements;
fields.insert(self.bootstrap_proxy_requirements);
fields.insert(self.context_setter_fields);
fields.insert(self.hook_exposed_requirements);
Self::renderable_fields(fields)
}

pub fn context_setter_fields(&self) -> RuntimeGlobals {
Self::renderable_fields(self.context_setter_fields)
}

pub fn render_lexical_declarations(
&self,
render_runtime_global: Option<&dyn Fn(RuntimeGlobals) -> Option<String>>,
) -> String {
let names = self
.lexical_fields()
.iter_names()
.filter_map(|(_, runtime_global)| {
let lexical_name = runtime_global.to_lexical_name()?;
if let Some(render_runtime_global) = render_runtime_global
&& let Some(value) = render_runtime_global(runtime_global)
{
Some(format!("{lexical_name}={value}"))
} else if runtime_global.should_initialize_as_object() {
Some(format!("{lexical_name}={{}}"))
} else if runtime_global.should_initialize_as_array() {
Some(format!("{lexical_name}=[]"))
} else {
Some(lexical_name.to_string())
}
})
.collect::<Vec<_>>();
if names.is_empty() {
String::new()
} else {
format!("var {};\n", names.join(", "))
}
}

pub fn render_context_setter_assignments(&self, runtime_context: &str) -> String {
let mut source = String::new();
for (_, runtime_global) in self.context_fields().iter_names() {
let (Some(property_name), Some(lexical_name)) = (
runtime_global.rspack_context_property_name(),
runtime_global.to_lexical_name(),
) else {
continue;
};
writeln!(
source,
"{runtime_context}{}={lexical_name};",
property_access([property_name], 0)
)
.expect("write to string should succeed");
}
source
}
}

#[derive(Debug, Default, Clone)]
pub struct RuntimeProxyMetadataArtifact(FxHashMap<ChunkUkey, RuntimeProxyMetadata>);

impl ArtifactExt for RuntimeProxyMetadataArtifact {
const PASS: IncrementalPasses = IncrementalPasses::CHUNKS_RUNTIME_REQUIREMENTS;
}

impl Deref for RuntimeProxyMetadataArtifact {
type Target = FxHashMap<ChunkUkey, RuntimeProxyMetadata>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for RuntimeProxyMetadataArtifact {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl From<FxHashMap<ChunkUkey, RuntimeProxyMetadata>> for RuntimeProxyMetadataArtifact {
fn from(value: FxHashMap<ChunkUkey, RuntimeProxyMetadata>) -> Self {
Self(value)
}
}

impl From<RuntimeProxyMetadataArtifact> for FxHashMap<ChunkUkey, RuntimeProxyMetadata> {
fn from(value: RuntimeProxyMetadataArtifact) -> Self {
value.0
}
}

impl FromIterator<<FxHashMap<ChunkUkey, RuntimeProxyMetadata> as IntoIterator>::Item>
for RuntimeProxyMetadataArtifact
{
fn from_iter<
T: IntoIterator<Item = <FxHashMap<ChunkUkey, RuntimeProxyMetadata> as IntoIterator>::Item>,
>(
iter: T,
) -> Self {
Self(FxHashMap::from_iter(iter))
}
}

impl IntoIterator for RuntimeProxyMetadataArtifact {
type Item = <FxHashMap<ChunkUkey, RuntimeProxyMetadata> as IntoIterator>::Item;
type IntoIter = <FxHashMap<ChunkUkey, RuntimeProxyMetadata> as IntoIterator>::IntoIter;

fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
5 changes: 5 additions & 0 deletions crates/rspack_core/src/cache/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ impl Cache for MemoryCache {
&mut compilation.cgc_runtime_requirements_artifact,
&mut old_compilation.cgc_runtime_requirements_artifact,
);
recover_artifact(
incremental,
&mut compilation.runtime_proxy_metadata_artifact,
&mut old_compilation.runtime_proxy_metadata_artifact,
);
}
}

Expand Down
Loading
Loading