feat(enhanced): align Webpack and Rspack layer support - #5039
ScriptedAlchemy wants to merge 34 commits into
Conversation
Rspack's layer-aware Module Federation stack (web-infra-dev/rspack#12977, #14912, #14913) changes what the public v2 wrapper receives: - ContainerManager.containerPluginExposesOptions rebuilt exposes from import/name only and dropped exposes.*.layer, so a layered expose was silently built unlayered. Preserve layer, including the empty string. - The manifest reader extracted the shared package/version from a fixed space-delimited position, which the structural identifiers (provide shared module [<key>]@<version> = ...) move; it also cast the container-entry bracket payload to an expose-pair array, which the layered [exposes, layers] tuple breaks with a TypeError. Decode the structural key by its length-prefixed components and validate both container payload generations (and array share-scope prefixes), keeping the legacy formats working. Shared records are still aggregated by package name only; representing concrete provider variants is coordinated separately with the native manifest producer.
🦋 Changeset detectedLatest commit: 8585d13 The changes in this PR will be included in the next version bump. This PR includes changesets to release 48 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@module-federation/devtools
@module-federation/cli
create-module-federation
@module-federation/dts-plugin
@module-federation/enhanced
@module-federation/error-codes
@module-federation/esbuild
@module-federation/managers
@module-federation/manifest
@module-federation/metro
@module-federation/metro-plugin-rnc-cli
@module-federation/metro-plugin-rnef
@module-federation/metro-plugin-rock
@module-federation/modern-js
@module-federation/modern-js-v3
@module-federation/native-federation-tests
@module-federation/native-federation-typescript
@module-federation/nextjs-mf
@module-federation/node
@module-federation/observability-plugin
@module-federation/playground
@module-federation/retry-plugin
@module-federation/rsbuild-plugin
@module-federation/rspack
@module-federation/rspress-plugin
@module-federation/rstest
@module-federation/runtime
@module-federation/runtime-core
@module-federation/runtime-tools
@module-federation/sdk
@module-federation/storybook-addon
@module-federation/third-party-dts-extractor
@module-federation/treeshake-frontend
@module-federation/treeshake-server
@module-federation/typescript
@module-federation/utilities
@module-federation/webpack-bundler-runtime
@module-federation/bridge-react
@module-federation/bridge-react-webpack-plugin
@module-federation/bridge-shared
@module-federation/bridge-vue3
@module-federation/inject-external-runtime-core-plugin
commit: |
Bundle Size Report10 package(s) changed, 33 unchanged. Package dist + ESM entry
Bundle targets
Consumer scenarios
Total dist (raw): 23.35 MB (+35.6 kB (+0.1%)) Bundle sizes are generated with rslib (Rspack). Package-root metrics preserve the historical report. Tracked subpath exports such as |
…ayers Rspack's layer-aware stack now emits the same identifier layouts as webpack's enhanced plugin: shared modules insert a ' (layer)' segment after the '(scope)' segment and keep 'name@version' at its legacy token position; container entries keep the '[[key, options]]' payload with a 'layer' inside the expose options when present. Drop the structural-key and tuple decoding that the earlier draft anticipated and parse the layer segment instead (for webpack provide identifiers too). Add a compatibility suite that runs the last published reader (@module-federation/manifest@2.8.2, aliased as a dev dependency) and the current source against the same Rspack-shaped identifiers: unlayered shares and containers (with or without a layered expose) read identically, layered shares are skipped by the old reader without failing, and the superseded structural/tuple shapes are documented as breaking it.
Resolve pnpm-lock.yaml by taking main's lockfile and regenerating it with pnpm install --lockfile-only for this branch's package.json additions.
|
A pkg.pr.new preview now exists for the current top of the Rspack stack, |
|
Two docs gaps against the checklist, from a read of the diff. |
…ack-layered-shared-metadata # Conflicts: # packages/runtime-core/src/remote/index.ts # pnpm-lock.yaml
Description
Let enhanced Webpack expose modules in a named layer, and preserve expose and shared layers in Webpack and Rspack manifests. A remote can build separate variants of the same source:
Module rules retain precedence. Omitting
layerpreserves existing behavior; an empty expose-layer string is rejected.Layer-specific relative shared requests now match by issuer layer and resolve their fallback from the importing module's directory. Manifest entries retain public expose aliases, shared requirements, and assets when chunks merge, exposes have multiple imports, or asset analysis is disabled. Unlayered shared IDs stay unchanged; no public
identityIdfield is added.At runtime, providers with the same scope, key, and version stay separate by layer. Lookup prefers the requested layer and uses an unlayered provider only when that layer is absent. Registration, singleton/version selection, remote cleanup, and snapshot asset matching follow that identity. Unlayered share-scope entries retain their existing format for older runtimes.
Review order
The generic Webpack graph collector and rollback option belong to the base PR, Collect Webpack stats from the compilation graph. Native Rspack still collects its data in Rust.
Verification
Latest local checks passed: runtime-core (141), SDK (70; one existing skip), bundler runtime (103), 18 Webpack layer/scalar-scope config cases, and 20 manifest-reader compatibility tests. The affected dependency builds and normal commit hooks passed.
Actual Federation 0.24.1 and 2.9.1 constructors pass 26 no-layer compatibility assertions in both host directions, including async factories, singleton/version selection, and mixed layered-provider/local-fallback behavior. The final Rspack adapter passes four same-scope/key/version layer cases across both registration orders and sync/async loading. The earlier ee3f65a runtime head passed hosted formatting, package builds, publishing checks, affected tests, and Node.js 20 verification. Final-head validation is tracked below.
Layered scope metadata transfers by reference; JSON or copying a scope does not preserve it. Unrelated full app/Metro/release suites were not run.
Related Issue
Layer-aware federation RFC.
Same-version shared modules across scopes is a separate follow-up. Provider metadata is not part of this stack; it has its own RFC and independent draft.
Types of changes
Checklist
The compiler compatibility fixture pins Rspack 1.3.9/Federation 0.13.1 as the older host and the published final Rspack d538c9c preview (2.2.7) with the current workspace runtime as the remote. All four old-host cases pass locally across default/custom scopes and remote-entry/manifest loading. The complete manifest suite passes 55/55 tests. The final published c4521e5 Federation suite (2.9.2) passes four actual native same-scope/key/version layer cases, both provider orders and eager/lazy loading, plus four sync/async adapter cases, 26 assertions with actual Federation 0.24.1/2.9.1, and two classic share-entry checks. Both Linux x64 and Mac ARM64 compiler preview workflows succeeded. Both final core heads pass hosted formatting, package builds, publishing checks, and affected package tests; Node.js 20 also passes on both heads; broader E2E jobs remain pending. The two shared preview checksums were refreshed after the Mac publication; an empty-store frozen installation verifies the compiler, wrapper, and Linux binary.
Two sync/async regressions cover compiler-provided share entries without enhanced
shareConfig. The seven formerly failing legacy config cases and two provider cases pass locally after the one-line compatibility fix.