Skip to content
Open
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
eff0ada
refactor(mf): add structural shared identity keys
ScriptedAlchemy Jul 22, 2026
7d654f7
feat(mf): add layer-aware shared module core
ScriptedAlchemy Jul 22, 2026
db65aeb
Merge remote-tracking branch 'origin/main' into codex/work-pr12977
ScriptedAlchemy Jul 27, 2026
36a3861
perf(mf): deduplicate provider resolution path
ScriptedAlchemy Jul 27, 2026
56fc0ca
perf(mf): reduce shared entry manifest overhead
ScriptedAlchemy Jul 27, 2026
654ac80
perf(mf): avoid archiving shared identity keys
ScriptedAlchemy Jul 27, 2026
6dab88a
perf(mf): precompute shared exports runtime data
ScriptedAlchemy Jul 27, 2026
9995069
fix(mf): preserve layered shared identities
ScriptedAlchemy Jul 27, 2026
73242f4
fix(mf): forward layers through enhanced share config
ScriptedAlchemy Jul 27, 2026
c58d0a8
fix(mf): provide shared fallback imports
ScriptedAlchemy Jul 28, 2026
81d616b
perf(mf): compact shared export fallback lookup
ScriptedAlchemy Jul 28, 2026
0a1d09f
perf(mf): require unambiguous export fallback
ScriptedAlchemy Jul 28, 2026
daeae0a
fix(mf): preserve layered runtime identities
ScriptedAlchemy Jul 29, 2026
997e40f
fix(mf): retain layered export usage
ScriptedAlchemy Jul 29, 2026
edc5abf
perf(mf): patch shared exports without typed stats
ScriptedAlchemy Jul 29, 2026
1617fe6
fix(mf): read shared manifest metadata structurally
ScriptedAlchemy Jul 29, 2026
335020f
fix(mf): retain public stats deserialization
ScriptedAlchemy Jul 29, 2026
17ef222
fix(mf): retain structural manifest identities
ScriptedAlchemy Jul 29, 2026
28a5176
fix(mf): encode unlayered consume identities
ScriptedAlchemy Jul 29, 2026
b86dcd3
fix(mf): merge shared export variants
ScriptedAlchemy Jul 29, 2026
addfee7
Merge remote-tracking branch 'origin/main' into codex/work-pr12977
ScriptedAlchemy Jul 29, 2026
45b50af
Merge remote-tracking branch 'origin/main' into codex/work-pr12977
ScriptedAlchemy Sep 7, 2026
06f9440
fix(mf): release provider map lock before add_include
ScriptedAlchemy Sep 8, 2026
8d8fe62
fix(mf): provide the module the enhanced consumer falls back to
ScriptedAlchemy Sep 8, 2026
ee8fa47
fix(mf): keep ConsumeSharedPluginOptions extendable
ScriptedAlchemy Sep 8, 2026
4fa21c4
fix(mf): keep the webpack identifier layout for shared modules
ScriptedAlchemy Sep 8, 2026
fa2a85b
Merge main into layer-aware shared module core
ScriptedAlchemy Sep 8, 2026
577a663
fix(mf): preserve distinct module identities and configured exports
ScriptedAlchemy Sep 8, 2026
4cb00dd
fix(mf): preserve shared fallback provider provenance
ScriptedAlchemy Sep 8, 2026
a1577ab
chore(mf): apply Rust formatting and documentation spelling
ScriptedAlchemy Sep 8, 2026
ecd6feb
fix(mf): collect exports for matched prefix shares
ScriptedAlchemy Sep 8, 2026
907852d
chore: merge main into mf layers
ScriptedAlchemy Sep 9, 2026
d097bab
fix(mf): derive prefix matching from consume requests
ScriptedAlchemy Sep 9, 2026
ca4e8cc
style(mf): format prefix request check
ScriptedAlchemy Sep 9, 2026
9ea0308
refactor(mf): move resolved provider lookup keys
ScriptedAlchemy Sep 9, 2026
b3c481e
fix(mf): match independent fallbacks by resolved resource
ScriptedAlchemy Sep 9, 2026
b176526
Merge remote-tracking branch 'origin/main' into feat/mf-layers
ScriptedAlchemy Sep 10, 2026
7660f9f
fix(mf): preserve independent fallback version origins
ScriptedAlchemy Sep 10, 2026
ff601a5
fix(mf): coalesce equivalent resolved shared artifacts
ScriptedAlchemy Sep 11, 2026
8479cc1
Merge remote-tracking branch 'origin/main' into stack-refresh/12977
ScriptedAlchemy Sep 14, 2026
2494408
Merge remote-tracking branch 'origin/main' into feat/mf-layers
ScriptedAlchemy Sep 15, 2026
f654628
refactor(mf): drop the redundant consume fallback source lookup
ScriptedAlchemy Sep 15, 2026
8703235
fix(mf): keep the provide fast path and reject empty shared layer names
ScriptedAlchemy Sep 16, 2026
89533c8
fix(mf): keep compiler-context resolution for unlayered relative cons…
ScriptedAlchemy Sep 16, 2026
738ce98
Merge origin/main into feat/mf-layers
ScriptedAlchemy Sep 22, 2026
a6494c4
Merge main into feat/mf-layers
ScriptedAlchemy Sep 29, 2026
29de6a6
fix(mf): sync test crate lockfile with workspace version
ScriptedAlchemy Sep 29, 2026
276d1eb
test(mf): expose provider identity and discovery regressions
ScriptedAlchemy Sep 30, 2026
542bba9
fix(mf): preserve provider behavior and drain discovered providers
ScriptedAlchemy Sep 30, 2026
4b8b932
fix(mf): distinguish independent shared container entry requests
ScriptedAlchemy Sep 30, 2026
75abea9
fix(mf): preserve Rust sharing API source compatibility
ScriptedAlchemy Sep 30, 2026
a71baf1
docs(mf): format Rust compatibility notes
ScriptedAlchemy Sep 30, 2026
c63ff54
docs(mf): use spell-check compatible Rust API wording
ScriptedAlchemy Sep 30, 2026
3f303e3
Merge commit '81eca8ee3a51a5082962465d67ef37818be7d3db' into api-compat
ScriptedAlchemy Sep 30, 2026
06742b2
test(mf): align regression crate lockfile with workspace release
ScriptedAlchemy Sep 30, 2026
a271043
chore: merge main into federation layers
ScriptedAlchemy Oct 22, 2026
cab82d4
fix(ci): use trunk baseline for branch-based PR stacks
ScriptedAlchemy Oct 21, 2026
29e9ad1
fix(ci): resolve published trunk through parent PR chain
ScriptedAlchemy Oct 21, 2026
4e1833f
fix: synchronize federation test crate lock version
ScriptedAlchemy Oct 22, 2026
5afe38d
ci: publish Linux and macOS previews together
ScriptedAlchemy Oct 22, 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
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions crates/node_binding/napi-binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2007,6 +2007,9 @@ export interface RawCompilerPlatform {

export interface RawConsumeOptions {
key: string
request?: string
issuerLayer?: string
layer?: string
import?: string
importResolved?: string
shareKey: string
Expand Down Expand Up @@ -2836,9 +2839,13 @@ export interface RawOptimizationOptions {
}

export interface RawOptimizeSharedConfig {
request?: string
issuerLayer?: string
shareKey: string
shareScope?: string | Array<string>
treeShaking: boolean
usedExports?: Array<string>
layer?: string
}

export interface RawOptions {
Expand Down Expand Up @@ -2943,6 +2950,8 @@ export interface RawProgressPluginOptions {

export interface RawProvideOptions {
key: string
request?: string
layer?: string
shareKey: string
shareScope: string | Array<string>
version?: string | false | undefined
Expand Down Expand Up @@ -3112,6 +3121,9 @@ export interface RawSharedContainerPluginOptions {
name: string
request: string
version: string
shareKey?: string
shareScope?: string | Array<string>
layer?: string
fileName?: string
library: JsLibraryOptions
}
Expand Down
33 changes: 33 additions & 0 deletions crates/rspack_binding_api/src/raw_options/raw_builtins/raw_mf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ impl From<RawRemoteOptions> for (String, RemoteOptions) {
#[napi(object)]
pub struct RawProvideOptions {
pub key: String,
pub request: Option<String>,
pub layer: Option<String>,
pub share_key: String,
pub share_scope: Either<String, Vec<String>>,
#[napi(ts_type = "string | false | undefined")]
Expand All @@ -135,6 +137,9 @@ impl From<RawProvideOptions> for (String, ProvideOptions) {
(
value.key,
ProvideOptions {
config_id: 0,
request: value.request,
layer: value.layer,
share_key: value.share_key,
share_scope: into_share_scope(value.share_scope),
version: value.version.map(|v| RawVersionWrapper(v).into()),
Expand Down Expand Up @@ -177,16 +182,26 @@ pub struct RawSharedContainerPluginOptions {
pub name: String,
pub request: String,
pub version: String,
pub share_key: Option<String>,
pub share_scope: Option<Either<String, Vec<String>>>,
pub layer: Option<String>,
pub file_name: Option<String>,
pub library: JsLibraryOptions,
}

impl From<RawSharedContainerPluginOptions> for SharedContainerPluginOptions {
fn from(value: RawSharedContainerPluginOptions) -> Self {
let share_key = value.share_key.unwrap_or_else(|| value.name.clone());
SharedContainerPluginOptions {
name: value.name,
request: value.request,
version: value.version,
share_key,
share_scope: value.share_scope.map_or_else(
|| ShareScope::Single("default".to_string()),
into_share_scope,
),
layer: value.layer,
library: value.library.into(),
file_name: value.file_name.map(Into::into),
}
Expand Down Expand Up @@ -217,17 +232,29 @@ impl From<RawConsumeSharedPluginOptions> for ConsumeSharedPluginOptions {
#[derive(Debug)]
#[napi(object)]
pub struct RawOptimizeSharedConfig {
pub request: Option<String>,
pub issuer_layer: Option<String>,
pub share_key: String,
pub share_scope: Option<Either<String, Vec<String>>>,
pub tree_shaking: bool,
pub used_exports: Option<Vec<String>>,
pub layer: Option<String>,
}

impl From<RawOptimizeSharedConfig> for OptimizeSharedConfig {
fn from(value: RawOptimizeSharedConfig) -> Self {
let request = value.request.unwrap_or_else(|| value.share_key.clone());
Self {
request,
issuer_layer: value.issuer_layer,
share_key: value.share_key,
share_scope: value.share_scope.map_or_else(
|| ShareScope::Single("default".to_string()),
into_share_scope,
),
tree_shaking: value.tree_shaking,
used_exports: value.used_exports.unwrap_or_default(),
layer: value.layer,
}
}
}
Expand Down Expand Up @@ -264,6 +291,9 @@ impl From<RawSharedUsedExportsOptimizerPluginOptions> for SharedUsedExportsOptim
#[napi(object)]
pub struct RawConsumeOptions {
pub key: String,
pub request: Option<String>,
pub issuer_layer: Option<String>,
pub layer: Option<String>,
pub import: Option<String>,
pub import_resolved: Option<String>,
pub share_key: String,
Expand All @@ -282,6 +312,9 @@ impl From<RawConsumeOptions> for (String, ConsumeOptions) {
(
value.key,
ConsumeOptions {
request: value.request,
issuer_layer: value.issuer_layer,
layer: value.layer,
import: value.import,
import_resolved: value.import_resolved,
share_key: value.share_key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rspack_core::{
DependencyType, ModuleDependency, ResourceIdentifier,
};

use crate::{ExposeOptions, ShareScope};
use crate::{ExposeOptions, ShareScope, SharedIdentity};

#[cacheable]
#[derive(Debug)]
Expand All @@ -15,6 +15,8 @@ pub struct ContainerEntryDependency {
pub share_scope: ShareScope,
pub request: Option<String>,
pub version: Option<String>,
pub(crate) share_key: Option<String>,
pub(crate) layer: Option<String>,
resource_identifier: ResourceIdentifier,
pub(crate) enhanced: bool,
dependency_type: DependencyType,
Expand All @@ -35,21 +37,38 @@ impl ContainerEntryDependency {
share_scope,
request: None,
version: None,
share_key: None,
layer: None,
resource_identifier,
enhanced,
dependency_type: DependencyType::ContainerEntry,
}
}

pub fn new_share_container_entry(name: String, request: String, version: String) -> Self {
let resource_identifier = format!("share-container-entry-{}", &name).into();
pub(crate) fn new_share_container_entry(
name: String,
request: String,
version: String,
share_scope: ShareScope,
share_key: String,
layer: Option<String>,
) -> Self {
let shared_identity = SharedIdentity::new(&share_scope, &share_key, layer.as_deref());
let resource_identifier = format!(
"share-container-entry-{}-{}",
&name,
shared_identity.identifier_key()
)
.into();
Self {
id: DependencyId::new(),
name,
exposes: vec![],
share_scope: ShareScope::Multiple(vec![]),
share_scope,
request: Some(request),
version: Some(version),
share_key: Some(share_key),
layer,
resource_identifier,
enhanced: false,
dependency_type: DependencyType::ShareContainerEntry,
Expand All @@ -71,6 +90,10 @@ impl Dependency for ContainerEntryDependency {
&self.dependency_type
}

fn get_layer(&self) -> Option<&rspack_core::ModuleLayer> {
self.layer.as_ref()
}

fn resource_identifier(&self) -> Option<&str> {
Some(&self.resource_identifier)
}
Expand Down
35 changes: 28 additions & 7 deletions crates/rspack_plugin_mf/src/container/container_entry_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use super::{
container_exposed_dependency::ContainerExposedDependency, container_plugin::ExposeOptions,
};
use crate::{
ShareScope,
ShareScope, SharedIdentity,
utils::{json_stringify, module_identifier_namespace, module_require_scope_name},
};

Expand All @@ -42,6 +42,8 @@ pub struct ContainerEntryModule {
enhanced: bool,
request: Option<String>,
version: Option<String>,
shared_share_key: Option<String>,
shared_layer: Option<String>,
dependency_type: DependencyType,
name: String,
}
Expand All @@ -59,8 +61,8 @@ impl ContainerEntryModule {
Self {
dependencies_block: Default::default(),
identifier: ModuleIdentifier::from(format!(
"container entry ({}) {}",
share_scope.key(),
"container entry {} {}",
share_scope.identifier_fragment(),
json_stringify(&exposes),
)),
lib_ident,
Expand All @@ -79,26 +81,33 @@ impl ContainerEntryModule {
enhanced,
request: None,
version: None,
shared_share_key: None,
shared_layer: None,
dependency_type: DependencyType::ContainerEntry,
source_map_kind: SourceMapKind::empty(),
name,
}
}

pub fn new_share_container_entry(
pub(crate) fn new_share_container_entry(
name: String,
request: String,
version: String,
share_scope: ShareScope,
share_key: String,
layer: Option<String>,
runtime_mode: RuntimeMode,
) -> Self {
let namespace = module_identifier_namespace(runtime_mode);
let lib_ident = format!("{namespace}/share/container/{name}");
let shared_identity = SharedIdentity::new(&share_scope, &share_key, layer.as_deref());
let identity_key = shared_identity.identifier_key();
let lib_ident = format!("{namespace}/share/container/{identity_key}");
Self {
dependencies_block: Default::default(),
identifier: ModuleIdentifier::from(format!("share container entry {}@{}", &name, &version,)),
identifier: ModuleIdentifier::from(format!("share container entry {identity_key}@{version}")),
lib_ident,
exposes: vec![],
share_scope: ShareScope::Multiple(vec![]),
share_scope,
factory_meta: Default::default(),
build_info: BuildInfo {
strict: true,
Expand All @@ -112,6 +121,8 @@ impl ContainerEntryModule {
enhanced: false,
request: Some(request),
version: Some(version),
shared_share_key: Some(share_key),
shared_layer: layer,
dependency_type: DependencyType::ShareContainerEntry,
source_map_kind: SourceMapKind::empty(),
name,
Expand All @@ -125,6 +136,12 @@ impl ContainerEntryModule {
pub fn name(&self) -> &str {
&self.name
}

pub(crate) fn shared_identity(&self) -> Option<SharedIdentity> {
self.shared_share_key.as_deref().map(|share_key| {
SharedIdentity::new(&self.share_scope, share_key, self.shared_layer.as_deref())
})
}
}

impl Identifiable for ContainerEntryModule {
Expand Down Expand Up @@ -160,6 +177,10 @@ impl Module for ContainerEntryModule {
}
}

fn get_layer(&self) -> Option<&rspack_core::ModuleLayer> {
self.shared_layer.as_ref()
}

fn source_types(&self, _module_graph: &ModuleGraph) -> &[SourceType] {
&[SourceType::JavaScript, SourceType::Expose]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ impl ModuleFactory for ContainerEntryModuleFactory {
dep.name.clone(),
dep.request.clone().expect("should have request"),
dep.version.clone().expect("should have version"),
dep.share_scope.clone(),
dep
.share_key
.clone()
.expect("share container entry should have a share key"),
dep.layer.clone(),
data.build_context.compiler_options.experiments.runtime_mode,
)
.boxed(),
Expand Down
Loading
Loading