Conversation
|
Status: reproduced on 1.4.3 with CI (build 114417, 180 jobs passed): the new test passes on every lane. The one red job is windows 2019 x64, where |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Essentials Run ID: 📒 Files selected for processing (7)
Included review availability: Your plan provides up to 10 included reviews per hour; 2 remain after this review. WalkthroughThe CommonJS extension loader now supports overridden ChangesCommonJS extension compilation
Suggested reviewers: Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to The CommonJS hook fallback preserves loader errors, excludes JSON, and is covered by integration tests for the changed loading paths. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
…compile When user code wraps Module._extensions['.js'] and replaces module._compile (pirates, @babel/register, sucrase/register, esbuild-register, ts-node), the built-in loader threw the build error before the replacement saw anything. Those packages also wrap the '.js' loader for '.tsx' and '.jsx', which forces the JavaScript loader, so a .tsx file that bun loads fine without the hook failed with 'AggregateError: 2 errors building' once the hook was installed. The built-in loaders now read the file from disk and call the replaced module._compile with it, as Node does. If the file cannot be read, the first error is thrown unchanged. The JSON loader is not affected.
c44dc9d to
5decc4f
Compare
|
Updated 1:47 PM PT - Sep 11th, 2026
❌ @robobun, your commit 5decc4f has 1 failures in
🧪 To try this PR locally: bunx bun-pr 42370That installs a local version of the PR into your bun-42370 --bun |
|
Another real-world case: Playwright Test ( Any type annotation in a spec breaks it: // e2e/d.spec.ts
import { test } from '@playwright/test'
test('probe', async () => { let r: number = 1 })// pw.config.ts
export default { testDir: '.' }
This blocks the "Playwright runs on Bun" path from the 1.4.0 release notes for any TypeScript suite. |
Problem
sucrase/registeroresbuild-registerinstalled,require("./comp.tsx")of a file that Bun loads fine with no hook throwsAggregateError: 2 errors building "/…/comp.tsx". A Flow-typed.jsfile fails the same way. Node loads both.Module._extensions[ext], replacemodule._compilewith their transform, and call the previous loader. For.tsxand.jsxthey wrap the.jsloader (Module._extensions[ext] || originalJSLoader), which forces Bun's JavaScript loader on a TSX file.fetchCommonJSModuleNonBuiltin<true>,src/jsc/bindings/ModuleLoader.cpp) throws the build error atif (!res->success). It only consults the replaced_compileafter a successful transpile.Fix
module._compilewas replaced, the loader reads the file from disk and calls the replacement with the text (new builtincompileFromHijackedExtensioninCommonJS.ts). Node's loader does the same: it reads the file and callsmodule._compile(source, filename)without parsing first._compilein Node either._compile, by design (require-extensions.test.ts, "secretly sync esm").docs/runtime/nodejs-compat.mdxnow says so.test/js/node/module/require-extensions.test.ts(new test fails on 1.4.3). Also ran all oftest/js/node/module/.Background
Module._extensions['.js']is the function Node calls to load a.jsfile. Bun's built-in entries are native and run only when user code calls them.m_overriddenCompileholds the value user code assigned tomodule._compileon one module object.Notes
Installed-package repro (
bun add sucrase esbuild-register esbuild):bun main.cjs sucrase/registeron 1.4.3 (same withesbuild-register):This branch, and Node v26.3.0 with the hook:
(
esbuild-registerstill rejectsflow.json both runtimes. esbuild has no Flow support, and the error is esbuild's own.)The test uses a hand-written 10 line copy of
pirates.addHook(), because tests cannot install from npm. It checks that the hook receives the exact bytes on disk, that a.tsxfile routed through the wrapped.jsloader works, that broken JSON still throwsJSON Parse errorand never calls_compile, that a file that cannot be read keepsBuildMessage: ENOENT reading "missing.js", and that a hook that does not replace_compilestill gets the build error. It runs in a subprocess because other tests in that file leave.jsmapped to the TypeScript loader.Scope decision: the other half of the original report (call the replaced
_compilefor files that Bun classifies as ES modules) is not in this PR and is not planned. #18686 chose the skip on purpose, a test pins it, anddrizzle-kit<= 0.31.9 withesbuild-registerworks on Bun only because of it.Self-review: checked every
return nullarm ofBun__transpileFilefor an empty error value with no pending exception (none reachable on this path), that the new lazy function is GC-visited and initialised beforebuiltinLoaderis reachable, thatfetchCommonJSModuleNonBuiltin<true>has one caller, and ran the scenario withBUN_JSC_validateExceptionChecks=1.