Skip to content

feat(v6): require Rspack 2 - #1490

Open
dannyhw wants to merge 12 commits into
dannyhw/v6from
dannyhw/rspack-2
Open

dannyhw wants to merge 12 commits into
dannyhw/v6from
dannyhw/rspack-2

Conversation

@dannyhw

@dannyhw dannyhw commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #1487 (dannyhw/v6).

Summary

Re.Pack 6 requires @rspack/core 2 (peer >=2) and drops Rspack 1. There's no runtime branching on the Rspack major. The change maps the options Rspack 2 renamed or moved, fixes the type fallout, and removes the Rspack 1 workarounds. webpack is unaffected. New projects from @callstack/repack-init get @rspack/core@^2.

Mapped options

  • experiments.parallelLoader: Rspack 2 removed it, so Re.Pack no longer sets it. Loaders run in parallel when their rule sets parallel: true, which the templates and tester apps already do.
    • The babel-swc-loader warning about it can no longer fire, so the warning and its hideParallelModeWarning option are removed.
  • experiments.cache: Rspack 2 ignores it silently, so REPACK_EXPERIMENTAL_CACHE produced no persistent cache. It now sets top-level cache: { type: 'persistent' }.
    • --reset-cache reads top-level cache for both bundlers. resetPersistentCache lost its per-bundler overloads and casts.
  • exportsPresence: Rspack 2's default is 'error', which fails on missing-export imports that React Native itself ships (React.unstable_Activity in renderApplication.js). Re.Pack sets module.parser.javascript.exportsPresence: 'auto' for Rspack.
  • RSPACK_PROFILE: it crashed start because published v2 binaries have no perfetto layer. It now defaults to the logger layer. The pre-1.4 profile handler is gone.

Rspack 2 behaviour changes handled

  • bundle --json: stats.toJson() now leaves out assets, chunks, chunk groups, entrypoints and modules unless asked for, even with preset: 'normal'. With no stats config, Re.Pack requests them explicitly. User presets are passed through.
  • Production source maps: absoluteResourcePath is now <context>/../../... and isn't resolved. SourceMapPlugin normalizes it.
  • repack-expo: the Module Federation runtime data: module's resource path is now percent-encoded. The Expo source map fix matches the encoded form.

Types

  • babel-swc-loader: SwcLoaderOptions is now a union on detectSyntax, so the loader uses its own non-union SwcConfig.
  • assetsLoader: it reads through small promise wrappers typed against InputFileSystem, because util.promisify picks the wrong overload of the v2 types.
  • RepackTargetPlugin: devServer is now false | DevServer, so it's narrowed before reading hot.

Rspack 1 workarounds removed

  • the profile handler for Rspack < 1.4
  • the SWC minimizer special case for 1.4.11; the Rspack minimizer is always Terser now
  • the parallel-loader rootContext workaround and the @rspack/core fallback lookup for SWC. Rspack 2 passes parallel loaders the right rootContext and _compiler.rspack.experiments.swc (checked in serial and parallel mode).

Tests and infra

  • Jest loads the ESM-only core through a custom test environment (jest.environment.js plus a moduleNameMapper bridge).
  • Integration markers and snapshots follow Rspack 2's output:
    • runtime module banners are // repack/polyfills
    • module factories use method shorthand
    • with MF v2, the polyfills runtime module now comes before embed_federation_runtime. MF still initializes in __webpack_require__.x(), after the polyfills, in both the test bundle and the real host bundle (MF 2.9.2).
  • New tests:
    • the cache config and cache reset
    • the exportsPresence default
    • the stats fallback
    • SourceMapPlugin path normalization: a real Rspack compile that fails without the fix
  • The catalog pin is now ^2.2.8. The old "1.6.2+ breaks MF v2 polyfill ordering; 1.6.4+ fails typecheck" notes don't apply to 2.2.8. @swc/helpers is ^0.5.23, the Rspack 2 peer.
  • One CI lane is enough with a single Rspack major, so CI is unchanged.

Docs

  • parallelLoader → per-rule parallel: true in the configuration guide and the babel-loader / babel-swc-loader pages
  • the Re.Pack defaults now list exportsPresence
  • new Rspack 2 section in the Re.Pack 5 migration guide
  • agent_context design doc rewritten for the single-major approach

Known issue (upstream, not fixed here)

In tester-app production bundles, 9 of about 1100 source map sources point one directory too shallow, e.g. apps/packages/repack/dist/modules/InitializeScriptManager.js. The affected sources are Re.Pack's own runtime modules, reached through the workspace symlink apps/tester-app/node_modules/@callstack/repack -> ../../../../packages/repack.

  • Rspack 2 itself reports the wrong relative resourcePath for these modules. The wrong path is what you get by resolving the link target against the link instead of its directory.
  • Rspack 1.6 got them right, except one require.context module that was already wrong on 1.6.
  • Dev-server source maps aren't affected: 1220/1220 [projectRoot] sources resolve.
  • I couldn't reproduce it outside tester-app yet, so it needs a minimal repro before it goes upstream.

Verification

Run on Rspack 2.2.8, Node 26:

Checks: pnpm build, pnpm typecheck, pnpm lint:ci and pnpm test, all with --force. All pass, including:

Suite Result
repack (Jest) 345
integration (Rspack + webpack) 122
repack-expo 125

Bundles:

  • tester-app production bundles: Rspack iOS + Android, webpack iOS + Android
  • MF v2 bundles from apps/tester-federation-v2/configs/*.mts, iOS + Android each: Rspack host, mini and expo-host-widget, webpack host and mini
  • bundle --json writes assets/chunks/modules again, and --stats minimal is respected

Dev server:

  • start serves iOS + Android
  • REPACK_EXPERIMENTAL_CACHE=1 writes node_modules/.cache/rspack: cold compile 11.2s, warm 2.7s
  • --reset-cache deletes that directory
  • RSPACK_PROFILE=OVERVIEW emits logger traces with no perfetto crash

Native apps: tester-app Debug ran against the Rspack 2 dev server on the iOS simulator (iPhone 17 Pro, iOS 27) and the Android emulator (Pixel 9).

  • Both loaded, including async chunks.
  • Editing src/App.tsx hot-updated the screen in place on both platforms, with component state kept.
    • iOS fetched only main.<hash>.hot-update.json, with no bundle reload.
    • Android logged [HMRClient] Processing bundle update.

I also checked out the first commit on its own: it typechecks and passes its Jest suite (340).

@vercel

vercel Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
repack-website Ready Ready Preview Oct 12, 2026 10:43am UTC

Request Review

@changeset-bot

changeset-bot Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b1b83ac

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@callstack/repack Major
@callstack/repack-init Major
@callstack/repack-plugin-expo-modules Major
@callstack/repack-plugin-nativewind Major
@callstack/repack-plugin-reanimated Major
@callstack/repack-dev-server Major

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

@dannyhw dannyhw changed the title feat!: require Rspack 2 feat(v6): require Rspack 2 Oct 9, 2026
@dannyhw
dannyhw added this pull request to stack #1491 October 9, 2026 23:41
Raise the @rspack/core peer to >=2 and build and test against 2.2.8.
Map the options Rspack 2 renamed or removed:

- Stop setting experiments.parallelLoader, which Rspack 2 removed.
  Parallel loading is opted into per rule with `parallel: true`. The
  babel-swc-loader warning about it could no longer fire, so it is
  removed together with the hideParallelModeWarning option.
- Rspack 2 passes parallel loaders a correct rootContext and the
  compiler's bundled SWC, so the babel-swc-loader uses both directly.
- REPACK_EXPERIMENTAL_CACHE sets and --reset-cache reads the top-level
  `cache` option, as Rspack 2 silently ignores experiments.cache.
- Fix the type fallout: a non-union SwcConfig for the babel-swc-loader,
  InputFileSystem-typed reads in the assets loader, and narrowing the
  now `false | DevServer` devServer option.

Jest loads the ESM-only core through a custom test environment, and the
integration markers and snapshots follow Rspack 2's output.
Rspack 2 changed the default of module.parser.javascript.exportsPresence
to 'error', which fails builds on missing-export imports that React
Native itself ships, such as `React.unstable_Activity` in
renderApplication.js. Default it to 'auto', matching webpack and
Rspack 1. Projects can still override it.
Published Rspack 2 binaries are built without the perfetto trace layer,
so `RSPACK_PROFILE` crashed `start` unless RSPACK_TRACE_LAYER was set.
Default to the logger layer, and drop the handler for Rspack < 1.4.
The SWC minimizer was only picked for Rspack 1.4.11, which Re.Pack no
longer supports, so the minimizer no longer depends on the bundler.
Rspack 2's stats.toJson() leaves out assets, chunks, chunk groups,
entrypoints and modules unless they are asked for, even with the
`normal` preset. When the project has no stats config, request them
explicitly so `bundle --json` writes the same stats as before.
Rspack 2 joins a module's absoluteResourcePath from the context without
resolving it, so files outside the project root, such as hoisted
node_modules in a monorepo, were named `<context>/../../...` in source
maps built without a dev server. Normalize the path.
…e source

Rspack 2 percent-encodes the resource path of the Module Federation
runtime `data:` module, so the malformed `webpack://` source it produces
no longer matched the raw prefix and was not renamed to
`webpack://module-federation/virtual-runtime-<hash>.js`.
Replace experiments.parallelLoader with per-rule `parallel: true`, drop
hideParallelModeWarning, list the exportsPresence default, and add a
Rspack 2 section to the Re.Pack 5 migration guide.
…lugin snapshots

Rspack 2 inlines the MF v2 bundler runtime as a URL-encoded data: URI, which
put an absolute local path in the snapshot, and colors inlined error messages
when color output is enabled, as it is on CI.

This branch was successfully deployed

1 active deployment
Preview — b1b83acb Deployed Oct 12, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant