feat: support Rspack 2 alongside Rspack 1 - reference implementation (to be broken down)#1393
Draft
dannyhw wants to merge 24 commits into
Draft
feat: support Rspack 2 alongside Rspack 1 - reference implementation (to be broken down)#1393dannyhw wants to merge 24 commits into
dannyhw wants to merge 24 commits into
Conversation
…d client files for rspack 1 and webpack
- detect installed @rspack/core major and adapt generated config: experiments.parallelLoader only under v1, exportsPresence 'auto' under v2 - read persistent cache config from both v1 (experiments.cache) and v2 (top-level cache) locations; auto-migrate legacy value under v2 with a warning - React Refresh: apply official @rspack/plugin-react-refresh v2 (optional peer) under rspack 2 via its integrator options (injectEntry: false + custom loader); vendor the client runtime files for webpack & rspack 1 manual wiring; drop the @rspack/plugin-react-refresh@1 dependency - load rspack commands lazily and fail fast with a clear error when running rspack 2 on Node < 20.19 (ESM-only package requires require(esm) support) - default --trace-* to the logger layer under rspack 2 (published binaries lack the perfetto trace layer) - verify @module-federation/runtime-tools is installed for MFv1 under rspack 2 - compile against @rspack/core@2 types; bridge ESM-only core into jest via a custom test environment
🦋 Changeset detectedLatest commit: 68925e4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- babelSwcLoader: split builtin:swc-loader-only options (rspackExperiments, transformImport, collectTypeScriptInfo, detectSyntax) off before calling the raw SWC transform API instead of casting - also more correct at runtime - cache handling: derive RspackConfigurationWithLegacyCache from Configuration['cache']/(Configuration['experiments'] & legacy key) so the accessor and migration helper need no casts; move the migration call from makeCompilerConfig (weakly-typed generic flow) to start/bundle where configs are concretely typed - bundle: split devServer off via rest-destructuring instead of delete + cast - parallelLoader probe: 'in' narrowing instead of a cast - version helper: type annotation instead of assertion on require()d JSON - start: keep the single irreducible cast (devServer augmentation vs Rspack's bundled DevServer type differ only by duplicated http-proxy-middleware type trees) with full reasoning in a comment
Establishes agent_context/ as dated documentation of agent-assisted work - a durable record of research, decisions, plans, and verification results. Conventions documented in agent_context/README.md and referenced from AGENTS.md.
Collaborator
Author
|
next step is going to be to split this pr into multiple prs, this branch will serve as a reference for work done until now |
…ng it Per maintainer feedback on #1393: when Rspack 2 ignores a configured experiments.cache, warn once and leave the config untouched instead of copying the value to the top-level cache option. --reset-cache still reads both locations via getRspackCacheConfig.
…ndor/ Per maintainer feedback on #1393: the adapted upstream files (verbatim from @rspack/plugin-react-refresh v2.0.2 apart from headers) live under vendor/react-refresh with a LICENSE recording provenance, are shipped as-is via the files allowlist, and are excluded from biome so they stay diffable against upstream. DevelopmentPlugin resolves them relative to the package root so the path works from both src/ and dist/.
jest.environment.js loads the aliased @rspack/core-v1 devDependency when RSPACK_MAJOR=1 (plain CJS require; v2 stays an ESM import) and exposes __RSPACK_MAJOR__. pnpm test:rspack1 runs the suite on the real Rspack 1 core surface; a lane-guard test asserts the loaded major matches the requested lane so a silently-ignored switch can never pass again. Honest scope: in-workspace version detection still resolves repack's own @rspack/core@^2 devDependency, so this lane covers the v1 core object and compilation surface, not version routing (doc 08 § Correction).
…ck 1 lab apps/tester-app moves to the new rspack2 named catalog and is the Rspack 2 example. apps/tester-app-rspack1 is a standalone app excluded from the workspace (own node_modules, repack installed from a packed tarball via pack-repack) because in-workspace repack's @rspack/core@^2 devDependency shadows any app-level v1 pin - it is the only surface that genuinely runs Rspack 1 (doc 08 § Discovery). Validated on-device (Android + iOS) for both apps: HMR/React Refresh, local + remote chunk loading, mini-app install/show/remove, all asset frames incl. remote assets (doc 08 § On-device validation).
Doc 08 gains the devDep-shadowing discovery (with the implemented-then- reverted loadRspack decision and the no-monorepo-leaks working agreement), the dual-major jest lane correction, and the on-device validation state. Doc 09 reflects the reference branch after the reworks; docs 01/02/03/05/06/07 get dated AMENDED/superseded notes. Doc 10 evaluates the maintainer feedback; the smoke-harness appendix matches the warn-only cache behavior and vendored file locations.
The default catalog's v1 pin was cosmetic: every workspace consumer already ran repack's @rspack/core@^2 devDependency (devDep shadowing, doc 08). The default catalog now pins ^2.1.2 (+ plugin-react-refresh, newer @swc/helpers); the rspack2 named catalog is gone, tester-app pins plain catalog: again, and both federation apps declare the refresh plugin like any real Rspack 2 app. The Rspack 1 surfaces stay explicit: the standalone apps/tester-app-rspack1 lab and pnpm test:rspack1. This put tests/integration's rspack lane (which imports @rspack/core directly) on v2 for the first time, surfacing output-format changes, not behavioral ones: custom runtime-module banners lost the webpack/runtime/ prefix, unminified module factories use shorthand method syntax, and the polyfills runtime module now precedes MFv2's embed_federation_runtime wrapper (polyfills still execute before __webpack_require__.x() is invoked - the invariant the tests now assert directly). Markers made version-agnostic, an Rspack 2 module-factory regex added, rspack-lane snapshots regenerated under 2.1.2.
Rspack 2 colorizes the diagnostics it inlines into error-stub modules when the environment enables color, so the CI run of the rspack lane produced bundles whose stub error strings embed escaped ANSI codes (backslash-u001b[31m etc.) while local colorless runs do not. normalizeBundle now strips both the raw and string-escaped forms, making the NativeEntryPlugin snapshots environment-independent (verified locally with and without FORCE_COLOR=3).
For @module-federation/enhanced 0.15.x/0.21.x under Rspack 2, embed_federation_runtime inlines a data: URI module whose URL-encoded source embeds the absolute path to webpack-bundler-runtime, so the snapshots carried machine-specific paths (local vs CI runner). normalizeBundle now also rewrites the encodeURIComponent form of the repo root.
README gains a start-here section pointing at doc 09 and the open work items; doc 08 commit map replaces the stale working-tree row with the actual pushed commits (CI green at 55b6739) and gains the CI snapshot-portability findings; doc 09 status header, PR 8 catalog instructions, porting deltas, and per-branch validation commands now match the flipped default catalog and final branch state.
dannyhw
added a commit
that referenced
this pull request
Jul 3, 2026
Introduce agent_context/ - dated documentation of substantial research and planning efforts (conventions in agent_context/README.md) - with the full rspack 2 adoption plan: breaking-changes inventory, impact analysis, dual-version support plan, decisions, verification results, implementation notes, the PR split plan, and the maintainer feedback evaluation for #1393.
dannyhw
added a commit
that referenced
this pull request
Jul 3, 2026
Introduce agent_context/ - dated documentation of substantial research and planning efforts (conventions in agent_context/README.md) - with the full rspack 2 adoption plan: breaking-changes inventory, impact analysis, dual-version support plan, decisions, verification results, implementation notes, the PR split plan, and the maintainer feedback evaluation for #1393.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Rspack 2 support to Re.Pack while keeping Rspack 1 fully working from the same release. Re.Pack detects the installed
@rspack/coremajor at runtime and adapts — no separate builds, no breaking changes for existing Rspack 1 / webpack users.Full research, decisions, and verification behind this PR live in
agent_context/rspackv2-jul2026/(added on this branch): breaking-changes inventory mapped to our code, dual-version plan, decided questions, an executed V1–V11 verification checklist against@rspack/core@2.1.2, and a React Refresh deep dive.What changed
Version detection (foundation)
getRspackVersion/getRspackMajorVersion/isRspack2helpers — resolve@rspack/core/package.jsoninstead of importing the package, so they're safe on any Node version and when@rspack/coreisn't installed.Config generation
experiments.parallelLoaderis only set under Rspack 1 (removed in v2 — verified silently ignored, i.e. dead config).module.parser.javascript.exportsPresence: 'auto'under Rspack 2 — v2 changed the default from'warn'to'error', which breaks builds on invalid imports inside node_modules (common in the RN ecosystem, tolerated by Metro). Overridable in project config.Persistent cache
experiments.cache→ top-levelcacheand silently ignores the legacy key (verified: no error, cache just off). Re.Pack now reads both locations, and under v2 auto-applies a legacyexperiments.cachevalue tocachewith a warning so users don't silently lose caching.--reset-cacheworks with both shapes.React Refresh (biggest piece — see agent_context/rspackv2-jul2026/06)
@rspack/plugin-react-refresh@1.0.0dependency (and its removeddeprecated_runtimePathsAPI) is gone.@rspack/plugin-react-refreshv2 plugin through its new integrator options (injectEntry: false+reactRefreshLoader: '@callstack/repack/react-refresh-loader'), keeping Re.Pack's per-entrypoint entry ordering and RN-aware loader. The plugin is a new optional peer dependency — Rspack 2 users install it alongside@rspack/core@2(a friendly error explains this if missing). It's ESM-only, so it's required lazily inside the v2 branch only.src/modules/reactRefresh/(MIT, adapted from the v2 plugin) and wired manually exactly as before — defines updated from the removed overlay flags to__reload_on_runtime_errors__: false.Commands & environment
Rspack X requires Node.js ^20.19.0 || >=22.12.0instead of an obscureERR_REQUIRE_ESMcrash (v2 is pure ESM). Bonus: loadingreact-native.config.jsno longer touches@rspack/coreat all.--trace-*defaults to theloggerlayer under v2 (published v2 binaries are built without perfetto — verified).ModuleFederationPluginV1pre-checks@module-federation/runtime-toolsunder v2 (no longer auto-installed by@rspack/core) with an actionable error.Types & tests
packages/repacknow compiles against@rspack/core@2types (other packages stay on the v1 catalog). Fallout handled without casts: non-unionSwcConfigalias (v2 madeSwcLoaderOptionsa union ondetectSyntax), loader-only SWC options split off before the raw transform call, cache types derived fromConfiguration['cache']with the legacyexperiments.cachelocation modeled explicitly, anddevServersplit off via destructuring inbundle. One irreducible cast remains instart(Re.Pack'sdevServeraugmentation vs v2's bundledDevServertype differ only by duplicated http-proxy-middleware type trees) - documented in a comment at the site.moduleNameMapperbridge exposes it, so all suites now run against the real Rspack 2 (280 tests, up from 234 — 4 suites previously silently type-only).Verification
pnpm build/typecheck/test(280/280) / biome — green across all 12 package tasks.parallelLoader, no parser override, cache accessor + migration, Node guard, and a full dev build with HMR + React Refresh using the vendored client files ✅parallelLoader,exportsPresence: 'auto', cache migration, Node guard, and a full dev build with HMR + React Refresh through the official v2 plugin (with Re.Pack's loader + entry ordering) ✅load_scriptinterception,jsonp+array-push+globalObject: 'self') executes correctly under v2; MF v1 + v2 (enhanced@2.6.0) build clean.Not in this PR (follow-ups per plan phases 3–4)
tests/metro-compat/tests/resolver-casesruns under v2 (needs device validation for HMR e2e)repack-init, templates, and website docs to default to Rspack 2 (decided, gated on the validation pass)