Skip to content

Cut Bun test skips down to the few cases Bun genuinely can't run#21239

Merged
alexander-akait merged 35 commits into
mainfrom
claude/bun-ignored-tests-54arh9
Jun 21, 2026
Merged

Cut Bun test skips down to the few cases Bun genuinely can't run#21239
alexander-akait merged 35 commits into
mainfrom
claude/bun-ignored-tests-54arh9

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Jun 21, 2026

Copy link
Copy Markdown
Member

Summary

webpack runs its test suite under Bun (and Deno) in CI, but a growing number of cases were turned off per-case via test.filter.js to work around Bun runtime quirks. This PR removes ~33 of those Bun skips by fixing the underlying cause on webpack's / the test harness's side wherever possible, so the Bun job runs almost the whole suite.

A handful of cases remain skipped under Bun because they exercise things Bun genuinely doesn't support yet (kept skipped, with precise TODO comments): ProfilingPlugin (node:inspector Session), lazy-compilation over HTTPS (HMR never delivers the update), an eval'd minified worker chunk (require undefined), require(esm) "module.exports" interop, and the persistent-cache variant of that case.

Highlights of the fixes:

  • Test harness: buffer messages in the fake Worker until onmessage is set and fix blob-URL handling (test/helpers/createFakeWorker.js); a node:vm dynamic-import preload shim for Bun (test/bun-preload.js); deterministic readdir ordering in a few CSS/hash snapshot configs; normalize JSC error/trap phrasing in stats and array-expectation checks.
  • Worker cases: attach the message listener before the top-level await so messages are not missed during async startup.
  • less cases: under Bun, pass implementation: require("less") so less-loader skips import("less"), which crashes Bun's node:vm SourceTextModule.link(); Node keeps the default ESM path.
  • require/esm-module-exports: assert webpack's require(esm) unwrapping against literal values on every runtime and gate only the native cross-check.
  • One library fix: keep the module build error message when Error.stack omits the message line, as JSC does (lib/errors/ModuleBuildError.js, with changeset + unit test).

No open issue; this is CI/runtime-coverage hardening.

What kind of change does this PR introduce?

Mostly test (enabling the Bun suite); includes one small fix in lib/errors/ModuleBuildError.js.

Did you add tests for your changes?

Yes — the change is largely test enablement (~33 previously-skipped cases now run under Bun), plus a new test/ModuleBuildError.unittest.js covering the V8 and JSC stack-message branches. Verified under Bun (worker-threads, full suite), Node, and Deno.

Does this PR introduce a breaking change?

No.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

n/a

Use of AI

Yes. I used Claude Code to investigate the Bun/JSC runtime failures (including isolating a node:vm SourceTextModule.link() crash to a minimal reproduction), implement the fixes, and verify the suite across Bun, Node, and Deno.

Under Bun, jest's vm `importModuleDynamically` callback resolving to a
`vm.Module` yields an empty namespace, so less-loader's `import('less')`
came back undefined. Coerce the callback result to `module.namespace` in
the Bun preload, then re-enable the less cases (Deno skips kept).
JSC (Bun) and some other engines emit a frames-only `Error.stack` without
the leading "Name: message" line V8 adds, so ModuleBuildError rendered loader
errors as bare stack frames with no message. Lead with the message when the
stack does not already contain it, then un-skip configCases/loaders/options
under Bun.
Bun (JSC) phrases the magic-comment syntax error and the JSON manifest parse
error differently than V8. Normalize both to the V8 form in the stats harness
(no-op on V8, which never emits those strings) and un-skip the two cases.
…p webpack-ignore

Bun (JSC) quotes the bad token and appends "Expected …" in magic-comment parse
errors where V8 does neither. Normalize to the V8 form in checkArrayExpectation
(no-op on V8) and un-skip configCases/css/webpack-ignore, which was mislabeled
as a less case but actually hit this phrasing difference.
Replace the vague "worker chunk does not run to completion" notes with the
diagnosed cause: a message queued while webpack's import() worker chunk loading
(Promise.race) is in flight stalls Bun's event loop. Also record why the logging
stats trace is engine-inherent (V8 vs JSC Error.stack shape and line:col).
…kip Bun

moduleScope matched the css bundle with /bundle.+.css/, which also matches the
.css.map source map; with readdirSync order unspecified, Bun picked the map file
so the linked stylesheet had no rules and getComputedStyle returned undefined.
Anchor the regex to .css. Deno kept skipped (separate undefined-CSS-export issue).
afterExecute snapshotted raw readdirSync output, whose order is
filesystem-dependent; Node happened to return alphabetical order (matching the
recorded snapshot) but Bun does not. Sort before snapshotting. Deno kept skipped
(separate undefined-CSS-export issue).
…orker HMR

Two Bun-specific issues in test/helpers/createFakeWorker.js:
- Bun implements the web Worker API, so assigning self.onmessage registers a
  native handler; forwarding parentPort messages to it too delivered every
  message twice (breaking HMR check() with reentrancy). Skip the forward on Bun.
- Bun's eval-worker module context is a blob: URL, from which require() of the
  emitted chunks (entry and hot-update) fails to resolve. Root require at a real
  file via module.createRequire.
Un-skip the three worker HMR cases; Node/Deno behavior is unchanged.
The case passes reliably on Bun now (verified 3x); remove the Bun-only filter.
findBundle matched bundle names with an unanchored regex, so `^bundle1` also
matched `bundle10`..`bundle17` and the first readdir match (order-dependent)
could be the wrong bundle with a different hash length. Anchor with a trailing
dot. Deno kept skipped (separate output difference).
Fixed by the createFakeWorker eval-worker require fix; verified passing on Bun
across normal, minimized, and source-map variants, and on Node.
The out-of-bounds call_indirect trap message differs by engine; the test already
tolerated several V8 wordings, so add JSC's "Out of bounds call_indirect". Deno
kept skipped (separate hard-panic).
The `this` external throws because top-level `this` is undefined in ESM; JSC
phrases it "undefined is not an object" vs V8's "Cannot read property...". Accept
both in the assertion.
The case passes on Bun now across Node/Web/WebWorker hot suites and on Node;
remove the Bun-only filter.
The worker attached parentPort.on after `await import()`; Bun drops a message
posted before the listener is attached during async worker startup (Node buffers
it). This case tests global Worker resolution, not top-level await, so move the
import into the handler and attach the listener synchronously. Deno kept skipped.
Earlier comments claimed the chunk-load promise never resolves; investigation
shows it does resolve and the listener does attach. The real cause: Bun drops a
worker message posted before the listener is attached when attachment is deferred
past the worker's async-module startup (Node/browsers buffer it). Reproduces
running the emitted bundle outside jest, so it is not a jest issue.
The logging stats snapshot embedded raw engine stack traces: V8 emits one
"at fn (file:line:col)" frame, while JSC (Bun) emits extra internal frames
(its LOADER_EXECUTION frame is unnamed so cutOffLoaderExecution can't trim it),
omits the function name, and reports different line:col. Normalize trace frames
to the in-test-dir file path so the snapshot is engine-independent.
…sal/webworker cases

Browsers queue messages posted to a worker until onmessage is assigned; the
worker module often sets it only after async (module) startup. The fake Worker
delivered via parentPort.on directly, so under Bun a message posted before
self.onmessage was set was lost (module workers), and Bun's web-Worker API also
double-dispatched. Define self.onmessage as an accessor with a message buffer:
this emulates the browser queue and prevents Bun's native double-dispatch. Un-skip
worker/universal, css/universal, target/universal-all-module-types,
module/issue-17014-webworker, worker/self-import.
Two engine differences broke the blob-URL worker on Bun: (1) the publicPath is
derived from self.location by stripping "blob:" and the last path segment, but
Bun's URL.createObjectURL returns "blob:<id>" with no path separator (Node:
"blob:nodedata:<id>") so the bare id became the publicPath — build the blob
location from options.originalURL instead; (2) the worker uses parentPort as a
global, which Bun does not surface implicitly — expose self.parentPort. With the
earlier onmessage-buffer change this also removes the prior JSC SIGABRT.
webpack correctly externalizes every node builtin for module output here (the
verification loop — all builtins load and every import("…") is emitted — passes
on Bun). The sole failure was `expect(typeof repl.start).toBe("function")`: Bun's
repl module is a stub with no start. Guard that one interactive-builtin check so
it runs where implemented. Deno kept skipped (separate hard-panic).
These workers used a real worker_threads Worker and attached parentPort.on only
after `await import(chunk)`. Bun's real MessagePort does not buffer a message
that arrives during the worker's async-module startup (Node/browsers do), so the
posted message was dropped. Attach the listener synchronously before the await
while keeping a top-level await, so the async-module worker output is still
exercised. Deno kept skipped.
The ProfilingPlugin inspector concurrency error no longer reproduces on current
Bun: the case passes under both --runInBand and --workerThreads (isolated and in
the full watch suite). Remove the Bun-only filter.
Investigating the layer segfaults pinpointed the root cause: a vm-loaded ESM
module (jest SourceTextModule) that statically imports any node builtin crashes
Bun (SIGSEGV/SIGILL), and the less package is ESM importing module/fs/etc. So
every less-loader case crashes the whole Bun run, not just one test. These were
optimistically un-skipped earlier; restore the Bun skip with the accurate cause,
and correct the layer/context comments.
less-loader's default `import("less")` runs through jest's vm and crashes
Bun (SIGSEGV) because a vm-loaded ESM module that statically imports a node
builtin aborts the process. Passing `implementation: require("less")` makes
the loader use the CJS less and skip the dynamic import. The inline
cases/loaders/less-loader case uses a thin wrapper loader to inject it.
The crash is a RELEASE_ASSERT in Bun's NodeVMSourceTextModule::link()
(node:vm), hit only when less-loader runs `import("less")` through jest's vm.
Pass `implementation: require("less")` only under `process.versions.bun` so
Node keeps exercising the default ESM path exactly as before.
…acle

webpack's `require(esm)` "module.exports" unwrapping is runtime-agnostic; only
the native cross-check (Module._load) needs Node's require(esm), which Bun does
not implement. Assert webpack's output against literal values on every runtime
and gate the native comparison behind `crossCheckNative` instead of skipping
the whole case under Bun.
@changeset-bot

changeset-bot Bot commented Jun 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 15e33b4

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

This PR includes changesets to release 1 package
Name Type
webpack Patch

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

@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

This PR is packaged and the instant preview is available (10f5fcc).

Install it locally:

  • npm
npm i -D webpack@https://pkg.pr.new/webpack@10f5fcc
  • yarn
yarn add -D webpack@https://pkg.pr.new/webpack@10f5fcc
  • pnpm
pnpm add -D webpack@https://pkg.pr.new/webpack@10f5fcc

@codecov

codecov Bot commented Jun 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.80%. Comparing base (40b972f) to head (15e33b4).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #21239      +/-   ##
==========================================
+ Coverage   92.77%   92.80%   +0.02%     
==========================================
  Files         591      591              
  Lines       64488    64565      +77     
  Branches    17920    17957      +37     
==========================================
+ Hits        59829    59918      +89     
+ Misses       4659     4647      -12     
Flag Coverage Δ
css-parsing 28.68% <0.00%> (-0.04%) ⬇️
html5lib 31.13% <0.00%> (-0.04%) ⬇️
integration 88.71% <83.33%> (-0.04%) ⬇️
test262 45.41% <0.00%> (-0.09%) ⬇️
unit 41.28% <100.00%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Declare the untyped `less`/`less-loader` modules and type the less-loader
wrapper so `tsc` on the test sources passes. Add a ModuleBuildError unit test
covering both the V8 (stack includes message) and JSC (frames-only) branches,
which also covers the previously-untested lines flagged by codecov.
Removing the Bun skip accidentally dropped the `process.getBuiltinModule`
capability check too, so the case ran on Node 12/14/16 (which lack it) and
failed with `__webpack_require__.wc is not a constructor`. Keep the gate; Bun
has `getBuiltinModule`, so it still runs there.
@codspeed-hq

codspeed-hq Bot commented Jun 21, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by ×2.9

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 142 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory benchmark "lodash", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 859 KB 127.6 KB ×6.7
Memory benchmark "wasm-modules-async", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 419.4 KB 330 KB +27.08%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing claude/bun-ignored-tests-54arh9 (15e33b4) with main (b9323eb)

Open in CodSpeed

These un-skips were too optimistic: they pass in the basic ConfigTestCases/cases
runs but fail under Bun in secondary suites. Restore the Bun skips for
watchCases profiling-plugin (inspector Session), hotCases lazy-compilation/https
(no HMR update), cases side-effects/issue-11673 (require undefined in eval'd
minified worker), and skip only the filesystem-cache variant of
require/esm-module-exports (nondeterministic persistent cache).
@alexander-akait alexander-akait changed the title Run the Bun test job with zero per-case skips Cut Bun test skips down to the few cases Bun genuinely can't run Jun 21, 2026
…variant

Bun only binds CJS `require` for `eval()` in strict mode; only the minified
eval-devtool output is sloppy at the top level and reaches the worker_threads
external via `require` inside `eval`. Narrow the Bun skip to that one variant so
the case runs under Bun everywhere else instead of being skipped entirely.
Bun ignores a runtime `NODE_TLS_REJECT_UNAUTHORIZED`, so the case's self-signed
HTTPS backend was never accepted under Bun's worker threads ("No update
available"). Point the backend at a test-local client that passes
`rejectUnauthorized: false` per request, scoping the bypass to this case, and
drop the Bun skip. Verified on Bun (worker threads, node + async-node) and Node.
@github-actions

Copy link
Copy Markdown
Contributor

Types Coverage

Coverage after merging claude/bun-ignored-tests-54arh9 into main will be
99.35%
Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
bin
   webpack.js98.77%100%100%98.77%91
examples
   build-common.js100%100%100%100%
   buildAll.js100%100%100%100%
   examples.js100%100%100%100%
   template-common.js98.21%100%100%98.21%72
examples/custom-javascript-parser
   test.filter.js100%100%100%100%
examples/custom-javascript-parser/internals
   acorn-parse.js100%100%100%100%
   meriyah-parse.js100%100%100%100%
   oxc-parse.js91.30%100%100%91.30%140, 142–143, 145, 147, 153–154, 161, 168, 90
examples/markdown
   webpack.config.mjs100%100%100%100%
examples/typescript
   test.filter.js100%100%100%100%
examples/typescript-non-erasable
   test.filter.js50%100%100%50%5
examples/virtual-modules
   test.filter.js100%100%100%100%
examples/wasm-bindgen-esm
   test.filter.js100%100%100%100%
examples/wasm-complex
   test.filter.js100%100%100%100%
examples/wasm-emscripten
   test.filter.js100%100%100%100%
examples/wasm-simple
   test.filter.js100%100%100%100%
examples/wasm-simple-source-phase
   test.filter.js100%100%100%100%
lib
   APIPlugin.js100%100%100%100%
   AsyncDependenciesBlock.js100%100%100%100%
   AutomaticPrefetchPlugin.js100%100%100%100%
   BannerPlugin.js100%100%100%100%
   Cache.js98.21%100%100%98.21%101
   CacheFacade.js100%100%100%100%
   Chunk.js99.72%100%100%99.72%39
   ChunkGraph.js100%100%100%100%
   ChunkGroup.js100%100%100%100%
   ChunkTemplate.js100%100%100%100%
   CleanPlugin.js99.15%100%100%99.15%207, 227
   CodeGenerationResults.js100%100%100%100%
   CompatibilityPlugin.js100%100%100%100%
   Compilation.js98.43%100%100%98.43%1618, 1937, 1944, 1952, 1974, 1977, 2917, 3396–3397, 3429, 4095, 4125, 4178–4179, 4183, 4188, 4204–4205, 4219–4220, 4225–4226, 4703, 4729, 514, 519, 5537, 5569, 5586, 5602, 5618, 5633, 5658–5659, 5661, 5989, 5994, 6000, 6003, 6015, 6017, 6021, 6037, 6052, 6084, 6138, 6162, 6276, 764–765
   Compiler.js99.56%100%100%99.56%1139–1140, 1148
   ConcatenationScope.js98.59%100%100%98.59%189
   ConditionalInitFragment.js100%100%100%100%
   ConstPlugin.js100%100%100%100%
   ContextExclusionPlugin.js100%100%100%100%
   ContextModule.js100%100%100%100%
   ContextModuleFactory.js97.40%100%100%97.40%258, 395, 418, 420, 424, 433–434
   ContextReplacementPlugin.js100%100%100%100%
   DefinePlugin.js99%100%100%99%171–172, 188, 207, 281
   DependenciesBlock.js100%100%100%100%
   Dependency.js98.50%100%100%98.50%471, 517
   DependencyTemplate.js100%100%100%100%
   DependencyTemplates.js100%100%100%100%
   DotenvPlugin.js98.41%100%100%98.41%378, 391–392
   DynamicEntryPlugin.js100%100%100%100%
   EntryOptionPlugin.js100%100%100%100%
   EntryPlugin.js100%100%100%100%
   Entrypoint.js100%100%100%100%
   EnvironmentPlugin.js97.14%100%100%97.14%49
   ErrorHelpers.js100%100%100%100%
   EvalDevToolModulePlugin.js100%100%100%100%
   EvalSourceMapDevToolPlugin.js100%100%100%100%
   ExportsInfo.js100%100%100%100%
   ExportsInfoApiPlugin.js100%100%100%100%
   ExternalModule.js98.50%100%100%98.50%1057, 1060, 445–449, 451, 597
   ExternalModuleFactoryPlugin.js100%100%100%100%
   ExternalsPlugin.js100%100%100%100%
   FileSystemInfo.js99.52%100%100%99.52%182, 2354–2355, 2358, 2369, 2380, 2391, 278, 3795, 3810, 3834
   FlagAllModulesAsUsedPlugin.js100%100%100%100%
   FlagDependencyExportsPlugin.js98.46%100%100%98.46%425, 434, 436, 440
   FlagDependencyUsagePlugin.js100%100%100%100%
   FlagEntryExportAsUsedPlugin.js100%100%100%100%
   Generator.js100%100%100%100%
   HotModuleReplacementPlugin.js100%100%100%100%
   HotUpdateChunk.js100%100%100%100%
   IgnorePlugin.js100%100%100%100%
   IgnoreWarningsPlugin.js100%100%100%100%
   InitFragment.js100%100%100%100%
   JavascriptMetaInfoPlugin.js100%100%100%100%
   LazyBarrel.js100%100%100%100%
   LibraryTemplatePlugin.js100%100%100%100%
   LoaderOptionsPlugin.js100%100%100%100%
   LoaderTargetPlugin.js100%100%100%100%
   MainTemplate.js100%100%100%100%
   ManifestPlugin.js100%100%100%100%
   Module.js98.50%100%100%98.50%1285, 1290, 1350, 1364, 1426, 1435
   ModuleFactory.js100%100%100%100%
   ModuleFilenameHelpers.js98.85%100%100%98.85%106, 108
   ModuleGraph.js99.73%100%100%99.73%1005
   ModuleGraphConnection.js100%100%100%100%
   ModuleInfoHeaderPlugin.js100%100%100%100%
   ModuleNotFoundError.js100%100%100%100%
   ModuleProfile.js100%100%100%100%
   ModuleSourceTypeConstants.js100%100%100%100%
   ModuleTemplate.js100%100%100%100%
   ModuleTypeConstants.js100%100%100%100%
   MultiCompiler.js99.69%100%100%99.69%659
   MultiStats.js100%100%100%100%
   MultiWatching.js100%100%100%100%
   NoEmitOnErrorsPlugin.js100%100%100%100%
   NodeStuffPlugin.js100%100%100%100%
   NormalModule.js97.90%100%100%97.90%1237, 1240, 1257, 1274, 1521, 1555, 1571, 1658, 2014, 2313, 2318–2328, 418, 422, 576
   NormalModuleFactory.js99.47%100%100%99.47%1083, 1392, 486, 498
   NormalModuleReplacementPlugin.js100%100%100%100%
   NullFactory.js100%100%100%100%
   OptimizationStages.js100%100%100%100%
   OptionsApply.js100%100%100%100%
   Parser.js100%100%100%100%
   PlatformPlugin.js100%100%100%100%
   PrefetchPlugin.js100%100%100%100%
   ProgressPlugin.js98.85%100%100%98.85%519–520, 525, 527, 591
   ProvidePlugin.js100%100%100%100%
   RawModule.js100%100%100%100%
   RecordIdsPlugin.js100%100%100%100%
   RequestShortener.js100%100%100%100%
   ResolverFactory.js100%100%100%100%
   RuntimeGlobals.js100%100%100%100%
   RuntimeModule.js100%100%100%100%
   RuntimePlugin.js100%100%100%100%
   RuntimeTemplate.js100%100%100%100%
   SelfModuleFactory.js100%100%100%100%
   SingleEntryPlugin.js100%100%100%100%
   SourceMapDevToolModuleOptionsPlugin.js100%100%100%100%
   SourceMapDevToolPlugin.js98.62%100%100%98.62%220, 224, 226, 419, 430, 891
   Stats.js100%100%100%100%
   Template.js100%100%100%100%
   TemplatedPathPlugin.js99.17%100%100%99.17%176–177
   UseStrictPlugin.js100%100%100%100%
   WarnCaseSensitiveModulesPlugin.js100%100%100%100%
   WarnDeprecatedOptionPlugin.js100%100%100%100%
   WarnNoModeSetPlugin.js100%100%100%100%
   WatchIgnorePlugin.js100%100%100%100%
   Watching.js100%100%100%100%
   WebpackError.js100%100%100%100%
   WebpackIsIncludedPlugin.js100%100%100%100%
   WebpackOptionsApply.js100%100%100%100%
   WebpackOptionsDefaulter.js100%100%100%100%
   buildChunkGraph.js99.87%100%100%99.87%371
   cli.js98.62%100%100%98.62%10, 119, 545, 577, 627, 897
   index.js99.72%100%100%99.72%184
   validateSchema.js94.67%100%100%94.67%100, 87, 89, 98
   webpack.js96.33%100%100%96.33%10, 198, 220, 222
lib/asset
   AssetBytesGenerator.js100%100%100%100%
   AssetBytesParser.js100%100%100%100%
   AssetGenerator.js100%100%100%100%
   AssetModule.js100%100%100%100%
   AssetModulesPlugin.js97.32%100%100%97.32%281, 305, 308, 36, 360, 41
   AssetParser.js100%100%100%100%
   AssetSourceGenerator.js100%100%100%100%
   AssetSourceParser.js100%100%100%100%
   RawDataUrlModule.js100%100%100%100%
lib/async-modules
   AsyncModuleHelpers.js100%100%100%100%
   AwaitDependenciesInitFragment.js100%100%100%100%
   InferAsyncModulesPlugin.js100%100%100%100%
lib/cache
   AddBuildDependenciesPlugin.js100%100%100%100%
   AddManagedPathsPlugin.js100%100%100%100%
   IdleFileCachePlugin.js97.92%100%100%97.92%71, 83, 91
   MemoryCachePlugin.js95.83%100%100%95.83%33
   MemoryWithGcCachePlugin.js93.15%100%100%93.15%106, 113–114, 122, 89
   PackFileCacheStrategy.js96.40%100%100%96.40%1250, 1350, 1354, 1416, 628, 647, 657–659, 661, 677–678, 683, 686, 688, 693, 698, 722, 728, 762, 768, 774, 779, 790, 799, 804–805, 807, 824, 830–831, 833
   ResolverCachePlugin.js100%100%100%100%
   getLazyHashedEtag.js100%100%100%100%
   mergeEtags.js100%100%100%100%
lib/config
   browserslistTargetHandler.js100%100%100%100%
   defaults.js99.31%100%100%99.31%1444–1446, 1454, 274, 277, 282, 286
   defineConfig.js100%100%100%100%
   normalization.js99.02%100%100%99.02%191–192, 258, 273
   

@alexander-akait alexander-akait merged commit 10f5fcc into main Jun 21, 2026
69 checks passed
@alexander-akait alexander-akait deleted the claude/bun-ignored-tests-54arh9 branch June 21, 2026 18:58
alexander-akait added a commit that referenced this pull request Jun 22, 2026
…-runInBand and unstable flags) (#21240)

* test: un-skip Deno tests that pass; keep only genuinely-unrunnable skips

Cut the Deno test skips down to the cases Deno 2.8.3 genuinely cannot run,
mirroring the Bun cleanup (#21239).

- All 27 test/cases skips pass under Deno; drop their Deno guards. The one real
  blocker was less-loader's import("less"), which hard-panics Deno's vm, so
  inject the CJS less (as already done for Bun) and run the case.
- Un-skip 13 configCases verified green in the full in-band Deno suite.
- Keep skips where Deno hard-panics executing ESM .mjs output via
  vm.SourceTextModule, and where cases fail/panic only cumulatively late in the
  in-band run (wasm ESM, worker/worklet, trusted-types/web-worker).

* test: run less-loader CSS cases under Deno; re-skip flaky worker cases

CSS: six css cases panicked only because less-loader's `import("less")`
hard-panics Deno's vm (same root cause as test/cases/loaders/less-loader).
Inject the CJS less on Deno too (as already done for Bun) and un-skip them:
css-auto, css-loader, import, local-ident-name, prefer-relative-css-import,
source-map-export-types. The remaining css skips emit ESM `.mjs` run through
node:vm SourceTextModule, which Deno aborts on — document that precisely.

Worker: the worker_threads cases un-skipped in the previous commit emit async
"Module not found" errors that leak across cases in the in-band Deno run
(e.g. worker-public-path's path bleeding into later worker tests), so they are
flaky in aggregate though each passes alone. Re-skip blob, custom-worker,
issue-17489, node-worker-async-node, web-worker and output/worker-public-path.

* test: run nearly all Deno-skipped cases by fixing the import.meta vm panic

Root cause of almost every Deno skip: Deno 2.8.3 hard-panics ("Module not
found", bindings.rs) the instant `import.meta` is accessed inside a
vm.SourceTextModule — no initializeImportMeta shape avoids it. webpack's ESM
output reads `import.meta.url` (auto publicPath, createRequire, __dirname), so
every ESM/universal/css/html/node case aborted the whole in-band run.

- Rewrite `import.meta` to a prepended object in the ESM runner under Deno
  (test/harness/runner/rewriteImportMeta.js, parsed via acorn so only real
  meta-properties are touched, never string/comment text). Node/Bun keep the
  initializeImportMeta callback.
- Extend the existing Bun CJS-`less` workaround to Deno for the less-loader
  cases (css-*, layer/*), whose `import("less")` also panics Deno's vm.
- Give worker/worker-self-reference-global a findBundle (its [name].js output
  never matched the default bundle0.js; it only runs where a global Worker
  exists, i.e. never on Node).
- Swallow a fake worker's late post-terminate error so it can't fail a later
  case.

This un-skips ~100 cases. The remaining Deno skips are the few web
worker_threads cases whose in-worker chunk load rejects asynchronously with a
blob:/data:/custom-publicPath URL Deno can't map, leaking into a later case.

* test: run the Deno test suite with jest's parallel workers

The import.meta vm fix removed the module-load panic that forced Deno to
--runInBand, so run Deno with parallel workers (matching Bun's
--workerIdleMemoryLimit=512MB recycling). Verified green: basictest 15735
passed, test+unittest 52953 passed, no panic. HotTestCases stay excluded for
Deno (their async cache/compilation tails outlive a suite's teardown under
Deno's event-loop timing); update the CI note accordingly.

* test: drop the unstable Deno flags, no longer needed

--unstable-node-globals, --unstable-bare-node-builtins and --unstable-detect-cjs
were required when the Deno CI was first added; Deno 2.8.3 makes them
default/no-ops for this workload (CJS require resolves bare node builtins, Node
globals are present, CJS is auto-detected). The full test:deno scope passes
without them: basictest 15735, longtest 15554, test+unittest 52953 — zero
failures from removing each flag or all three.

* test: un-skip all Deno worker cases by overriding the worker self.location

A Deno worker's globalThis.location is a read-only "data:text/javascript," (the
eval-worker URL), so createFakeWorker's `self.location = new URL(...)` was
silently ignored and webpack derived a bogus "data:text/" publicPath, making
in-worker chunk loads miss and leak an uncaught error into a later case. Use
Object.defineProperty to actually override it (Node/Bun accept either). Also
handle the expected worker load error in output/worker-public-path (its worker
URL is the intentionally-fake workerPublicPath).

This un-skips the last 8 Deno-skipped cases: worker/{blob,custom-worker,
issue-17489,self-import,web-worker,worklet}, trusted-types/web-worker and
output/worker-public-path. The eval-worker bootstrap is CJS and Deno's node-ESM
output uses bare builtins, so restore --unstable-detect-cjs and
--unstable-bare-node-builtins (--unstable-node-globals stays dropped).

* test: replace the Deno --unstable-bare-node-builtins flag with an import map

webpack's node-target ESM output imports builtins bare (e.g. `import "fs"`),
which Deno resolves only with --unstable-bare-node-builtins. Map every bare node
builtin to its `node:` specifier via an import map instead, dropping that flag.
--unstable-detect-cjs stays: Deno needs content-based CJS detection for webpack's
mixed `.js` output (a forced package.json "type":"commonjs" breaks ESM-syntax
`.js` library outputs). Verified: basictest 15867 passed, 0 failures.

* docs: ask for a short Use-of-AI sentence in templates and commit descriptions

Require the Use-of-AI disclosure to be one or two short sentences wherever it
appears — issue templates, the PR template, and the commit description.

* docs: make the compact-by-default rule general, not AI-only

Keep every issue/PR template section and the commit description body compact by
default, expanding only when the task's complexity needs it.

* test: drop the last Deno unstable flag via a worker_threads shim

Route Deno's eval-worker bootstraps and CJS `.js` worker entries through
temporary `.cjs` files in a worker_threads monkeypatch, so the test suite runs
with zero unstable flags (was --unstable-detect-cjs).

* docs: keep the compact-by-default rule general, drop AI-specific wording

* test: de-flake nested async-modules runtime-performance budget

The assertion used a 100ms wall-clock budget; its only real failure mode is an
exponential async-DAG regression that hangs, so a loaded CI runner could starve
microtasks past 100ms and flake. Raise the budget to 2000ms, which still catches
the hang.
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