feat: add rspack 2 types and dual-major test infrastructure#1398
Open
dannyhw wants to merge 4 commits into
Open
feat: add rspack 2 types and dual-major test infrastructure#1398dannyhw wants to merge 4 commits into
dannyhw wants to merge 4 commits into
Conversation
Bump @callstack/repack's @rspack/core devDependency to ^2.1.2 (the workspace catalog stays on v1) and absorb the type-level fallout with zero runtime behavior change for Rspack 1 / webpack users: - SwcLoaderOptions became a union discriminated on detectSyntax in v2 - introduce a local non-union SwcConfig alias and split builtin:swc-loader only options off before calling the raw swc transformSync (also more correct at runtime) - narrow devServer before reading .hot in RepackTargetPlugin (the key can be false in v2 types) - rest-destructure devServer off the config in the bundle command instead of delete (not assignable to v2's bundled DevServer type, and unused for bundling) - one documented cast in the start command: Re.Pack's devServer type augmentation and Rspack 2's bundled DevServer type are incompatible solely because each pulls proxy types from a different copy of http-proxy-middleware, and devServer cannot be stripped there because the dev server flow reads it back from compiler.options - getRspackCacheConfig accessor reading the persistent cache config from both the Rspack 1 (experiments.cache) and Rspack 2 (top-level cache) locations, with derived cache types extended for the legacy location @rspack/core v2 is ESM-only which Jest's sandboxed CJS runtime cannot load, so tests now run through a custom test environment that loads the real core outside the sandbox and bridges it back via moduleNameMapper. The environment is parameterized on RSPACK_MAJOR (v2 via import(), v1 via require of the aliased @rspack/core-v1 devDependency), exposes __RSPACK_MAJOR__ for major-gated assertions, and a permanent lane-guard test asserts the loaded major matches the requested lane. CI gains a Rspack 1 unit-suite lane, a Windows lane running the suite under both majors (the require(esm) loading path is Windows-sensitive), and the main-branch Node 18/20 matrix lanes run with RSPACK_MAJOR=1 since Rspack 2 requires Node ^20.19.0 || >=22.12.0. HermesBytecodePlugin test expectations are made platform-agnostic for the Windows lane.
…ndows resolveProjectPath composed the result via string replacement plus path.join: joining enough ../ segments onto rootDir to reach the filesystem root yields a bare root ending in a separator, and concatenating the rest of the path after it produced a double-separator prefix that Windows path resolution interprets as a UNC path (e.g. [projectRoot^2]/shared/utils.js with rootDir /project/root resolved to \\shared\utils.js\ instead of \shared\utils.js). Resolve segment-by-segment with path.resolve instead, add a regression test for the root-collapse case, and make the existing expectations platform-agnostic (resolved paths carry a drive letter and win32 separators on Windows).
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jul 6, 2026
dannyhw
commented
Jul 6, 2026
getRspackCacheConfig preferred experiments.cache over the top-level cache option, but a merged or dual-major config can carry both keys (e.g. the experimental cache defaults set experiments.cache while a user config sets top-level cache). Which location is active depends on the installed Rspack major, so --reset-cache now collects both locations instead of picking one.
dannyhw
commented
Jul 7, 2026
dannyhw
left a comment
Collaborator
Author
There was a problem hiding this comment.
codex review: posting two actionable findings from the re-review.
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
Re.Pack builds and tests green against Rspack 2, with zero runtime behavior change for Rspack 1 / webpack users. This PR bumps
@callstack/repack's@rspack/coredevDependency to v2 for types and tests (the workspace catalog stays on v1), absorbs the type-level fallout, and adds the dual-major test infrastructure that every later PR in the stack relies on.Stack position: PR 2c, stacked on PR 2b #1397 (
feat/rspack-2-node-guard) ← #1394 ←main. Reference implementation: #1393. Design doc:agent_context/rspackv2-jul2026/design.md.What's inside
Rspack 2 devDependency + type fallout (no runtime change)
@rspack/core@^2.1.2and@swc/helpers@^0.5.23aspackages/repackdevDependencies — source now compiles against v2 types while remaining runtime-compatible with both majors.SwcLoaderOptionsbecame a union discriminated ondetectSyntaxin v2 — a local non-unionSwcConfigalias inloaders/babelSwcLoader/options.tskeeps the spread-and-override option helpers working.builtin:swc-loader-only keys (rspackExperiments,transformImport,collectTypeScriptInfo,detectSyntax) are destructured off before calling the raw SWCtransformSync(also more correct at runtime).bundle.tsrest-destructuresdevServeroff the config instead ofdelete— it isn't needed for bundling and is not assignable to v2's bundledDevServertype.start.ts, Re.Pack'sdevServertype augmentation and Rspack 2's bundledDevServertype are incompatible solely because each pullsproxytypes from a different copy of http-proxy-middleware.devServercan't be stripped there — the dev-server flow reads it back fromcompiler.options. The cast carries its full reasoning in a comment; the genuine fix (aligning@callstack/repack-dev-server's proxy types with rspack's bundled ones) is possible future work.RepackTargetPluginnarrowsdevServerbefore reading.hot(the key can befalsein v2 types).getRspackCacheConfigaccessor inresetPersistentCache.tsreads the persistent cache config from both the Rspack 1 (experiments.cache) and Rspack 2 (top-levelcache) locations, with derived cache types extended for the legacy location. Behavior-neutral — the user-facing warning for the legacy location lands in a later stack PR.Dual-major Jest lane
@rspack/corev2 is ESM-only, which Jest's sandboxed CJS runtime cannot load (createRequireinside the sandbox is wrapped by Jest and loops back into the module registry). Tests now run through a custom test environment (jest.environment.js) that loads the real core outside the sandbox with Node's real module system and bridges it back viamoduleNameMapper(jest.rspack-core-bridge.js,__esModule-marked so Babel import interop keeps named imports working).The environment is parameterized on
RSPACK_MAJOR(default2): v2 viaawait import('@rspack/core'), v1 via plainrequireof the aliased"@rspack/core-v1": "npm:@rspack/core@^1.7.12"devDependency (CJS, so no reliance on cjs-module-lexer named-export synthesis). It exposes__RSPACK_MAJOR__for major-gated assertions, and a permanent lane-guard test (src/__tests__/rspackTestLane.test.ts) asserts the loaded core's major matches the requested lane, so a silently-unwired lane can't pass. New script:test:rspack1(cross-env RSPACK_MAJOR=1 jest).CI lanes
pnpm turbo run test:rspack1).windows-latestlane running the repack unit suite under both majors — therequire(esm)loading path of@rspack/core@2is Windows-sensitive.RSPACK_MAJOR=1— repack's Jest environment defaults to the v2 devDep, and Rspack 2 requires Node^20.19.0 || >=22.12.0.permissions: contents: readto both touched workflows (flagged by code scanning on feat: add rspack version detection helpers #1394).Pre-existing bug fix:
resolveProjectPathon Windows (found by the Windows lane)Standing up the Windows CI lane surfaced a real pre-existing product bug:
resolveProjectPathcomposed its result via string replacement +path.join, and when the[projectRoot^N]up-level navigation reached the filesystem root, the bare-root-plus-concatenation produced a double-separator prefix that Windows resolves as a UNC path (e.g.[projectRoot^2]/shared/utils.jswith rootDir/project/rootresolved to\\shared\utils.js\). Fixed at the root cause by resolving segment-by-segment withpath.resolve, with a regression test for the root-collapse case; existing test expectations are made platform-agnostic (resolved paths carry a drive letter and win32 separators on Windows). Split into its own commit.HermesBytecodePlugintest expectations got the same platform-agnostic treatment (test-only).Design decision: plain import, no project-context resolution
@rspack/coreis loaded with a plainimport— shipped code carries no project-context resolution or workspace-aware workarounds. The consequence is monorepo-only: in-workspace apps resolve repack's own devDep (v2) instead of their manifest's pin. That is accepted and handled at the fixture level (standalone, tarball-installed test apps in a later stack PR) rather than in published code — see the design doc for the reasoning.Same consequence for the v1 unit lane's honest scope: version-detection paths still resolve repack's own v2 devDep in-workspace, so the v1 lane exercises the real v1 core object and compilation surface, not version-routing logic.
Validation
All run at the repo root unless noted:
pnpm turbo run typecheck test --forcepnpm test(inpackages/repack)pnpm test:rspack1(inpackages/repack)pnpm lint:ciChangeset
Intentionally no changeset: this PR is behavior-neutral for users (devDeps, types, test/CI infrastructure). The user-visible Node-version error message ships with PR 2b (#1397) and carries the changeset there.