fix(core): avoid cloning URL objects in ESM resolution#1338
Conversation
Rsdoctor Bundle Diff AnalysisFound 13 projects in monorepo, 1 project with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 core/mainPath:
📦 Download Diff Report: core/main Bundle Diff Generated by Rsdoctor GitHub Action |
There was a problem hiding this comment.
Pull request overview
This PR addresses a DataCloneError that occurred on Node 24 when reused non-isolated workers ran through Rstest's ESM resolution while Node's native TypeScript loader hook was active. The root cause: passing URL objects across the loader-hook worker boundary triggered structured-clone failures. The fix normalizes the parent argument of import.meta.resolve to a string file:// URL, returns absolute specifiers as href strings, and tightens how the static link callback selects an origin (only relative specifiers use the referencing module; bare specifiers fall back to testPath).
Changes:
- Centralize
import.meta.resolveusage behind aresolveModulehelper in bothloadEsModule.tsandloadModule.ts, always passing a string parent URL; add acreateRequire-based fallback inloadEsModule.tsfor environments withoutimport.meta.resolve. - Stop passing
URLobjects for absolute specifiers — use.hrefstrings consistently. - In
vm.SourceTextModule.link, passreferencingModule.identifieras the origin only for relative specifiers so bare/subpath imports keep resolving from the original test path, and drop the incorrect cast ofreferencingModuletoImportCallOptions.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/src/runtime/worker/loadEsModule.ts | Adds resolveModule helper with string parent URL, createRequire fallback; fixes link callback to pass options + origin separately. |
| packages/core/src/runtime/worker/loadModule.ts | Mirrors the resolveModule helper and .href normalization for the CJS-output loader. |
| packages/core/tests/runner/loadEsModule.test.ts | Adds regression tests covering ESM resolution after a native TS load and bare static imports resolving from the test path. |
| packages/core/tests/runner/fixtures/nativeTsLoader.ts | New .ts fixture used to trigger Node's native TypeScript loader before the resolution test. |
| packages/core/tests/runner/fixtures/bare-parent/package.json | New fixture package declaring a #fixture-pkg subpath import. |
| packages/core/tests/runner/fixtures/bare-parent/bare-parent-pkg/index.mjs | Target module for the #fixture-pkg subpath import. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
This PR fixes a Node 24 native TypeScript loader interaction where reused non-isolated workers could throw
DataCloneError: Cannot clone object of unsupported type.during ESM resolution. Rstest now passes string parent URLs toimport.meta.resolveinstead ofURLobjects, preserves absolute specifiers asfile://strings, and keeps bare static imports resolving from the original test path while relative linked assets still resolve from the referencing module.Checklist