Repository navigation
Conversation
… await every async one The statements a wrapper runs before its body (init_x() calls, require_x() calls, __reExport calls) were grouped by kind: sync init calls first, then one await of the async ones, then everything else. An export * of a wrapped module was never awaited. Both reorder module evaluation against the module graph. They now stay in source order. Once an async dependency is seen, every later dependency joins that statement as await __promiseAll([init_a(), init_b(), ns = require_c()]), so each one starts before the wrapper suspends and the body runs after all settle. import() of an async module in the same bundle printed init_a().then(...). Called from inside a's own first synchronous segment, init_a() returns undefined and the .then throws. It now defers the call to a microtask, like import() of a sync module already did. A module that imports an async module through an import cycle could miss the async flag: the depth-first walk read a dependency's flag while that dependency was still on the stack. The propagation is now a worklist over reverse edges, so it reaches a fixpoint. __promiseAll is marked live from the parts that hold the import statements that join it, so an unwrapped entry point gets the helper too.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. ℹ️ Recent review info
WalkthroughThe linker now joins async ESM dependencies without the ChangesAsync ESM initialization
AST mutable accessor removal
Suggested reviewers: Priority: Merge Risk:
|
|
Updated 7:34 PM PT - Oct 29th, 2026
❌ @robobun, your commit c9eff65 has 1 failures in
🧪 To try this PR locally: bunx bun-pr 41601That installs a local version of the PR into your bun-41601 --bun |
…der change The bundle of libraries.js now calls each module's dependencies in source order. The same js and jsc hashes were produced on every CI platform.
… export star The re-exporter appends __reExport(exports, exports_r) right after the init_r() of the same record, so it joins the awaited list even though no later record exists.
…argets before deferring Emit await Promise.all([...]) through an unbound Promise symbol instead of the __promiseAll runtime helper. The helper needed a per-part liveness count that mirrored the prefix's join rule, which broke twice; an unbound symbol is reserved by the renamer and needs no bookkeeping. __promiseAll leaves runtime.js and the runtime imports table. import() of an async module calls init_foo() first and only defers when the call returns undefined, which happens inside foo's own first synchronous segment. This keeps a top-level await import() whose target imports the awaiter back evaluating at once, the same self-deadlock skip the runtime applies, while the re-entrant case resolves after foo settles instead of throwing on undefined.then.
There was a problem hiding this comment.
Beyond the inline findings, I also checked whether the new awaited export * in convertStmtsForChunk.rs puts a top-level await into an unwrapped file under --format=iife/cjs: it does, but only where should_remove_import_export_stmt already emits await init_x() for a plain import of the same async module on main, so this is the existing behavior extended to the export * twin rather than a new class.
Extended reasoning...
The output-format concern was traced through LinkerContext.rs append_dependency (unchanged for async static imports, which already produce the await in unwrapped files regardless of format) and the new can_await gate in convertStmtsForChunk.rs, which only excludes __commonJS and sync __esm wrappers. No security-sensitive surface is touched; the two inline findings are the open items.
Findings marked 🟡 are optional suggestions and need no follow-up push.
…barrel's body The barrel waits for its `export *` target, and that target calls `import()` on a module that reads the barrel. The module starts inside the call and reads `undefined`. main's bundle reads the value, because its barrel does not wait.
There was a problem hiding this comment.
Code review completed
Nothing new to post: everything this review found is already covered by existing comments on this pull request or didn't merit a separate one.
Still open from earlier reviews (2):
- 🔴
src/bundler/linker_context/convertStmtsForChunk.rs:292—Bun users whose lazily loaded barrel re-exports a module that imports back into a top-level-await entry get a bundle th… - Also unresolved: 1 minor or pre-existing.
If you have decided not to act on one of these findings, resolve its thread (a reply alone leaves it open) and the next review stops counting it. To review this commit again now, use Re-run on its "Claude Code Review" check.
An awaited export star changed two shapes that run on main: a barrel behind an awaited import() of its importer did not settle, and an importer with one async import and one async export star continued after a sibling. It waits for a decision on import cycles through import().
An `export *` of an async module is not awaited, as on main. From that statement on, the prefix now has main's layout: the later sync `init_x()` calls, the `await`, then the `init_x()` of the `export *` and the other later statements. With that call in its source position, 7 of 2000 generated graphs that complete on main were left unsettled. Tests: four cases hold main's output around an `export *` of an async module. Two cases pin a CommonJS import before the first async dependency: it runs where an ES import runs on main.
…ler-wrapper-init-order
…endency The statements that a wrapper runs before its body keep the order of the import statements while none of them is for an async dependency. With an async dependency (an `import` of an async module, or an `export *` of one) the prefix is what main prints: each sync `init_x()`, the `await`, then the other statements. No statement moves across an `await`. The earlier cut kept source order up to the first async dependency. Two sibling modules that share a top-level-await module then ran a CommonJS import of the second one before the CommonJS import of the first one: a lazy route with `reflect-metadata` and `tsyringe` threw where main runs. The change is now made on main's `InsideWrapperPrefix`. Out of this branch: the `(init_a() || Promise.resolve().then(init_a))` form of `import()`, the `Promise.all` join (#42046 fixes `__promiseAll is not defined`), the top-level await flag (#37770), and one call for two imports of one async module. Tests: the cases that depend on those parts are removed. New cases hold main's output for a CommonJS import before an async import, and for an `export *` of an async module. The unsplit mode of the graph fuzzer has a deadline for each child, a list of entries with no verdict, and a baseline binary.
…ler-wrapper-init-order
…irst The case pinned the old order of the build without `--aot`: the module that throws ran in front of the CommonJS file that the entry point imports before it. The CommonJS file runs first now. The two builds still differ in what `require()` of the running entry point does.
… start order of two dependencies against node `InsideWrapperPrefix` gets a unit test module. It appends every list of up to seven statements and compares the result with the layout: source order when no statement is for an async dependency, else each sync dependency, one `await`, then the other statements. It also runs every pair of lists of up to four statements through one prefix with `reset()` between them. `bundler_edgecase` gets a table of the order in which a file starts two dependencies, for a file with no wrapper and for a wrapped file. The four pairs with no async dependency run. The six pairs with one are todo and hold node's order. Where node is installed, each case that names node as its reference also runs node on its sources. New pinned cases: a sync `export *` that calls `import()`, an `import()` of a module that is running, a CommonJS file that requires its importer, and a CommonJS import before the generated JSX runtime import. One case expected `a end` where node prints it later. That line is gone.
…ler-wrapper-init-order
…that requires its importer
|
@dylan-conway you pointed at this PR for the call order in #44823 (comment). This head does less than the "Call order" fix of #44823, so two decisions are open. What this head does. A list of dependency statements keeps source order only when no dependency in it is async. A list with an async dependency prints the same bytes as main, so 1. Is the price acceptable? These run on main and change here. In each, bun 1.2.22 and esbuild print what this head prints. Six cases pin them.
2. Who owns the lists with an async dependency? 6 of the 10 orders in @Jarred-Sumner this PR changes the expected output of one case of #47129 in |
| itBundled("edgecase/CommonJSImportThatRequiresItsImporterRunsBeforeLaterImport", { | ||
| files: { | ||
| "/entry.js": /* js */ ` | ||
| const { render } = await import("./page.js"); | ||
| console.log("entry got", typeof render); | ||
| `, | ||
| "/page.js": /* js */ ` | ||
| import "./legacy.cjs"; | ||
| import { theme } from "./theme.js"; | ||
| export function render() { | ||
| return theme.name; | ||
| } | ||
| `, | ||
| "/legacy.cjs": /* js */ ` | ||
| const { render } = require("./page.js"); | ||
| console.log("legacy renders", render()); | ||
| `, | ||
| "/theme.js": /* js */ ` | ||
| console.log("theme"); | ||
| export const theme = { name: "dark" }; | ||
| `, | ||
| }, | ||
| format: "esm", | ||
| run: { error: "TypeError: undefined is not an object (evaluating 'theme.name')" }, |
There was a problem hiding this comment.
🟡 (optional) Users whose CommonJS file requires the ES module that imports it now get a bundle that exits 1 with TypeError: undefined is not an object (evaluating 'theme.name'), where main's bundle and bun run on the sources print theme, legacy renders dark, entry got function. With the source-order prefix (src/bundler/LinkerContext.rs:5164-5167) require_legacy() runs before init_theme(), so the require("./page.js") inside legacy.cjs calls render() while theme is still uninitialized. The PR lists this as a price; a working bundle becoming a startup crash is the consequence to weigh.
Why this was flagged
Input is the test fixture: entry.js await import("./page.js"), page.js import "./legacy.cjs"; import { theme } from "./theme.js"; export function render() { return theme.name }, legacy.cjs const { render } = require("./page.js"); console.log("legacy renders", render()), theme.js export const theme = { name: "dark" }. The new source-order branch at src/bundler/LinkerContext.rs:5164-5167 prints page's prefix as import_legacy = __toESM(require_legacy()); init_theme();. legacy.cjs runs first, its require("./page.js") prints as (init_page(), __toCommonJS(exports_page)), the re-entrant init_page() returns undefined (src/runtime.js:329-338), render is a hoisted function so it is callable, and theme.name reads the hoisted var theme before init_theme() assigned it, so a TypeError is thrown and the entry's await import() rejects. On the base branch append_sync_dependency inserted init_theme() at index 0, so theme ran before legacy and the bundle exited 0 printing theme, legacy renders dark, entry got function. No safeguard applies: validate_tla only rejects require of async modules, and this cycle is sync.
Verification: Branch: append_sync_dependency now does self.sync_dependency_indices.push(self.stmts.len()); self.stmts.push(stmt) (LinkerContext.rs:5164-5167), so the prefix becomes import_legacy = __toESM(require_legacy()); init_theme();. Inside require_legacy(), the re-entrant init_page() returns immediately because __esm (src/runtime.js:329-338) has already set fn = 0.
There was a problem hiding this comment.
This is right. It is item 3 of "The price" in the description, this case pins it, and #41601 (comment) asks the maintainers whether it is acceptable.
Who runs these files:
- Node rejects the sources:
ERR_REQUIRE_CYCLE_MODULE. bunon the sources prints the three lines only when nopackage.jsonsays"type": "module". With it,bunthrowsReferenceError: Cannot access 'theme' before initialization.- The bundles of bun 1.2.22 and of esbuild throw the same TypeError as this branch.
- The bundles of 1.2.23 to main run, because they print
init_theme()aboverequire_legacy().
The alternative is to keep main's order in a list whose CommonJS dependency is in an import cycle with the importer. The linker has no cycle information for files today, so that needs a new pass. It is not built. This thread stays open until a maintainer decides.
Problem
bun buildruns a CommonJS import, an externalrequire()or anexport *after a wrapped ES import that the source lists later.reflect-metadata,tsyringeand oneimport():tsyringe requires a reflect polyfill.append_sync_dependency(src/bundler/LinkerContext.rs) inserts each syncinit_x()above the other statements.Fix
test/bundler/bundler_edgecase.test.ts, 43 new cases: 25 fail on main, 13 aretodo. Self-reviewed: 23 concerns in the last round, 19 addressed (Notes).Background
var init_x = __esm(() => {...})wraps a module thatimport()orrequire()reaches. An importer callsinit_x()before its own code.tsyringeerror where main runs (Notes).Downsides
undefinedor a throw. Six pinned cases differ from node, or frombunon the sources, where main does not (Notes). One throwsTypeError: undefined is not an object (evaluating 'init_page().then')where main exits 0.--splitting(bundler(splitting): run an entry's earlier imports before shared code #44495).--minify: +4 bytes where aninit_x()now splits twovarstatements.Notes
Where the cases come from. No issue on this tracker reports it. Differential runs of bundles against
nodeandbunon the unbundled files found it. Other projects met it and worked around it:edobry/minskypull 1282 (merged 2026-05-25): a production crash, "Bun 1.2.23's bundler ... reordersimport "reflect-metadata"AFTER otherinit_*()calls". It shows the 1.2.21 bundle beside the 1.2.23 bundle.dennisofficial/atlaspull 1332 (merged 2026-10-20): "the compiled binary raninit_esm5()(tsyringe's runtime check) beforerequire_Reflect()".asocialmedia/socialpull 129 (merged 2026-09-13):@simplewebauthn/serverreachestsyringethrough@peculiar/x509, with no import order in user code.Hugo-Dz/exeissue 21 (open, Bun 1.3.10).vitejs/viteissue 21866 reports the samereflect-metadataandtsyringeinversion as a bug of another bundler.It is a regression: bun 1.2.22 prints the right order. In #22704 the first commit (
cd4417d01fa) still called sync dependencies in source order ("Non-async imports can be called directly"). The insertion cursorsync_dependencies_endcame with5c2dc264fc, with no test for the new order. The runtime had the same failure (#4677), andtest/js/bun/resolve/resolve.test.tsholds its fix. TheIsCommonJSrow of the table in #44495 is this bug without code splitting.#44823 (closed for the narrower #44876) listed this order first among its "five fixes that wrapped files need", all of which "fail on
mainwithout--splitting", and a review reply there names this PR for it (#44823 (comment)). Its fix was wider: source order in every list, each async dependency started in place, oneawaitlast. Of its five fixes, this PR has the call order for a list with no async dependency. #42046 has the__promiseAllhelper, and #45949 the async flag on an import cycle.A real package.
bun build entry.mjson 1.2.23 to main, with--target=bun,browserandnode:error: tsyringe requires a reflect polyfill. Please add 'import "reflect-metadata"' to the top of your entry point.Theimport()wrapsapp.mjs, and the entry printsinit_app()aboverequire_Reflect(). Node andbunon the sources, the bundle of bun 1.2.22 and the bundle of this branch printapp ok functiontwo times. An entry that importstsyringeitself, belowreflect-metadata, fails in the same way with--target=bunandbrowser.The rule. Main prints the statements in three groups: every sync
init_x(), oneawaitof the async ones, then everything else (require_x(),__reExport, theinit_x()of anexport *, and incjsandiifeoutput therequire("x")of an external or builtin import). This branch prints them in source order when the list has no async dependency:When the list has an
importof an async module, or anexport *of one, the three groups stay. The new statements inInsideWrapperPrefixonly push in source order and, at the first async dependency, move the syncinit_x()calls to the front. From there the code is main's.The linker makes one list for each part range of a file. A wrapped file has one. An unwrapped file starts a new one after each import of an unwrapped module, so the rule applies to each list (
edgecase/CommonJSImportBeforeWrappedESMImportAfterUnwrappedImport). A file that keeps a__commonJSwrapper (importandmodule.exportsin one file) has the same list, with noimport()in the bundle (edgecase/WrappedESMImportAfterCommonJSImportInCommonJSWrapper).Why not source order up to the first async dependency. The previous revision of this branch did that: a CommonJS import that the source lists before the first async dependency ran before the
await. A wrapper with two async dependencies starts both withPromise.all. The first one stops at itsawait, and the second one then runs its leading CommonJS import at once:di.cjsrequirestsyringe, andconfig.mjshas a top-level await. Node,bun, main, 1.2.22 and esbuild run this. That revision threwtsyringe requires a reflect polyfill, becausetsyringeran beforereflect-metadata. Three cases hold node's output for this family:edgecase/CommonJSImportBeforeAsyncImportRunsAfterEarlierSiblingBody(the route without packages),CommonJSImportBeforeAsyncImportRunsAfterWaitingImportCycleMemberandCommonJSImportBeforeAsyncImportInImportCallTargetRunsAfterCallerCode. They have no sync ES import in a list, so they do not reach the new statements. They are guards for a later change of the lists with an async dependency.The price. Four things run on main and change here. In each, bun 1.2.22 and esbuild print what this branch prints. Six cases pin them, and the first four also run node on the sources.
import()that runs while a list runs.appimportsrouter.cjs, thenstore.router.cjscallsimport()on a page with a top-level await. Animport()of an async module of the bundle prints asinit_page().then(...)(src/js_printer/lib.rs, esbuild's form), so the page starts inside the call. On mainstoreran first, out of source order, so the page read whatstoresets. Nowrouter.cjsruns first, and the page readsundefined. Node printsready, because node starts the page after the synchronous code. A syncexport *in the place of the CommonJS import is the same. With animportof an ES module in that place, main printsundefinedtoo. Cases:edgecase/ImportCallInCommonJSDependencyRunsBeforeLaterImport, the same after the code of an unwrapped module, andImportCallInExportStarDependencyRunsBeforeLaterImport.import()on the page, the page is running at that call, and the bundle throwsTypeError: undefined is not an object (evaluating 'init_page().then'). Main's bundle of the same files exits 0. The TypeError is on main for everyimport()of a module that is running. This PR makes one more graph reach it. Case:ImportCallInCommonJSDependencyThenImportCallOfRunningModule.pageimportslegacy.cjs, thentheme.legacy.cjscallsrequire("./page.js")and readsthemethrough it.bunruns the other imports ofpageinside thatrequire(). In a bundle the wrapper ofpageis running, so therequire()returns at once. On mainthemeran first, so the bundle ran. Here it throwsTypeError: undefined is not an object (evaluating 'theme.name'). Node rejects the sources (ERR_REQUIRE_CYCLE_MODULE).bunruns them when nopackage.jsonsays"type": "module", and throwsReferenceError: Cannot access 'theme' before initializationwhen one does. Case:CommonJSImportThatRequiresItsImporterRunsBeforeLaterImport. An alternative is to keep main's order in a list whose CommonJS dependency requires its importer. It needs a graph check in the linker and is not built.CommonJSImportRunsBeforeGeneratedJSXImport.Apart from these, a bundle that ran only because a later ES import ran first now runs as node runs its source. That is the fix from the other side:
needs.cjsreads whatsets.mjssets, the source listsneeds.cjsfirst, and only the bundles of 1.2.23 to main print the value. No switch restores that order. To move the import up does, on every version.What is not fixed. The order in which a file starts two dependencies, for a file with no wrapper and for a wrapped file. Node starts them in statement order in all ten rows, and so does the bundle of bun 1.2.22.
edgecase/DependencyStartOrderhas one case for each cell: 8 run, 12 aretodo.require("x")incjsoutput)export *of CommonJSexport *of a sync ES moduleexport *of CommonJSexport *of a sync ES moduleexport *of an async ES moduleexport *of an async ES moduleRow 10 is the
init_z(); await init_y()order that the review reply on #44823 left to this PR. It is not fixed here. Rows 5 to 10 with real packages:reflect-metadata,tsyringe, then a module with a top-level await still throws (edgecase/CommonJSImportBeforeWrappedESMImportWithLaterAsyncImport,todo). Also as on main:--splittingthrow on 1.2.22 too (bundler(splitting): run an entry's earlier imports before shared code #44495).Rows 5 to 10 need three things that each change bundles that run on main: an
import()of a running module that does not throw, anexport *of an async module that is awaited, and a decision on how two async siblings start (together, as now, or one after the other). Thetodocase and the real-package entry have an importer with no wrapper. Source order before the firstawaitonly in such a file is not built or measured here.Boards. Bundles are built by a debug build of main
3396aead750and of this branch merged with main3a9ea00437f. The fix is the same code since then.2000 generated graphs (CommonJS modules,
export *, import cycles, top-level await,import()), bundles and sources on node 26.3.0:Two limits of this board. About 90% of its wrappers are async, so it draws few of the lists that change. And no file of it calls
import()while a list runs, and no CommonJS file requires its importer, so it cannot draw the price above: the "exit code" and "0" rows hold only for such graphs.The repo's graph generator (
test/bundler/splitting-fuzz.ts) without code splitting, 300 seeds,bunas the reference: the bundle agrees with the source on every read and every order in 111 seeds on main and in 200 here. With main's binary as the baseline no seed is worse. That row cannot be anything else: the generator moves one setter whose only reader is the next import.The graph fuzzer.
splitting-fuzz.tshad one check: code splitting with and without chunk folding.checkUnsplitis a second check on the same generator. It adds two shapes from a random stream of their own, so the pinned seeds of the folding check keep their graphs: a CommonJS file before an ES import that reads what it sets, and anexport *. It builds without code splitting and compares every read and every order of top-level effects with a run ofbunon the sources. With a second binary as a baseline it reports only the facts that the baseline's bundle has and this bundle does not.bun scripts/splitting-fuzz.ts <bun> <graphs> --unsplit [--baseline=<bun>]runs it over many seeds. Each child process has a deadline now, and an entry whose unbundled run fails is listed apart. Four seeds are pinned inbundler_edgecase.test.ts. All four fail on main.What stays different from node. All of these are the same on main.
import()of an async same-bundle module starts the module inside the call. Node starts it after the caller's synchronous code.export *of an async module is not awaited.awaitof a dependency, and later withPromise.all. Node runs the importers that are ready in import order. An importer of two async modules can so continue after a later importer of one.--splittingruns a shared chunk before the entry's body (bundler(splitting): keep import order when an entry point's chunk takes no fold #44028, bundler(splitting): run an entry's earlier imports before shared code #44495).src/runtime/bake/hmr-module.ts) has its own order. This PR does not change it.Not in this PR. Earlier revisions of this branch carried more. Each part left because it changed bundles that run on main with no regression to undo, or because another PR has it. The order change that stays also changes such bundles (above). It stays because it is the regression.
import()of a module that is running throwsTypeError: undefined is not an object (evaluating 'init_a().then'). A fix has to choose what thatimport()does: wait for the module (a bundle that catches the TypeError today then never settles) or resolve at once.ReferenceError: __promiseAll is not definedin an unwrapped file with two async dependencies: bundler: define __promiseAll when an unwrapped file awaits two async ESM wrappers #42046.--compile --bytecode: bundler: record the ESM module record's TLA flag from the awaits the printer emits #37770.export *, node's order after an async dependency, a later start forimport(), and a serial join of siblings (rows 5 to 10 above).Other open PRs. #46578 adds
InsideWrapperPrefix::append_directiveto keep"use strict"above theinit_x()calls. A directive is only printed incjsandiifeoutput, where no dependency is async, so after this PR it stays first with or without that method. #42105 and #42046 touch the__promiseAllcode that this PR leaves as it is. Two lines of the body of #46786 say that this PR rewrites theexport *call and orders it. It orders it only in a list with no async dependency. The draft #45529 is stacked on this branch.Costs. A list with an async dependency prints the same bytes as on main. A list without one prints the same statements in another order. With
--minify, main merges adjacentvarstatements, and aninit_x()(or a run of them) that now stands between two of them splits one: +4 bytes. The firstvaris a CommonJS import or, incjsandiifeoutput (the default with--bytecode), therequire()of an external or builtin import. The second is another such import or the firstvar,letorconstof the file. Measured: 829 to 833 bytes incjsoutput with builtin imports, 852 to 856 iniifeoutput, 864 to 868 with one CommonJS import before the firstconstof the file, 929 to 933 in a__commonJSwrapper, and 0 in an__esmwrapper (919 bytes), where the names are declared outside. At link time the change is one index pushed for each sync dependency, and one rotation of the list at its first async dependency in place of main's insert for each sync dependency. The binary gains 628 bytes of machine code: the.textof thebun_bundlercrate goes from 2,101,163 to 2,101,791 bytes (cargo build -p bun_bundler --release, x86_64 Linux, one codegen unit, before link-time optimization).Self-review. Six rounds. The fifth reviewed a head that kept source order up to the first async dependency, and reproduced the route above. Its disposition was to keep source order only in a list with no async dependency. That is this revision. The sixth kept the source change as it is and asked for the record: the whole price with a pinned case for each part, the ten rows, node as a run reference, a unit test of the list, the third-party reports, and a question to the maintainers (in a comment below). 23 concerns: 19 addressed, 4 in part. Not done:
import()while a list runs, a CommonJS file that requires its importer). Its reference isbunwith the async transpiler off, which does not run CommonJS in node's order, so a verdict on those shapes needs node as the reference. The pinned cases have it.export *before the runtime import) and aniifebuild of the external-import row.awaitin a file with no wrapper. Nothing here builds that.Mutations. The unit test (
inside_wrapper_prefix_testsinLinkerContext.rs, run bybun run rust:test) fails for each of:reset()withoutin_source_order = true,reset()without the clear of the indices,append_async_dependencywithoutleave_source_order(), androtate_leftforrotate_right. A build without theleave_source_order()call for anexport *of an async module failsedgecase/ImportCallInAsyncExportStarDependencyRunsAfterLaterImportand no other case. Main is the mutant forappend_sync_dependency: 25 cases fail.Changes in existing tests.
bundler_bytecode_portable: thelibraries.jspins (jseb0e8220…,jsc21177816 bytes, main:7b8ce5d1…, 21177808 bytes). That bundle has 22__esmwrappers and 2882__commonJSwrappers, and an external import prints asrequire()in it. Four lists change. In each, aninit_x()now stands below therequire()of a node builtin (url,inspector/promises,fs,path) that the source imports first. Both bundles print64 libraries, failed: [].test/aot/code-from-disk.test.ts, the case "a file of the program that requires the entry point then catches what a module of the graph throws" (AOT: fixes for modules, classes and Workers, WebKit upgrade, shorter compiler docs #47129): itsmain.tsimportsasks.cjs, thenthrows.ts, andasks.cjsrequiresmain.ts. It pinned the old order for the build without--aot("A bundle runs the module that throws in front of the CommonJS file"). The CommonJS file runs first now, soprintsstarts with two more lines.differs, the output of the--aotbuild, is unchanged.run()insplitting-fuzz.tshas a deadline of 60 s for each child.Suites run with a debug build of this branch merged with main
9fe1cd6caa5:bundler_edgecase(239 pass, 24todo),bundler_splitting,esbuild/default,bundler_promiseall_deadcode,cyclic-imports-async-bundler,bundler_dynamic_import_dce,dynamic-import-tla-cycle,bundler_cjs2esm,bundler_cjs,bundler_regressions,esbuild/splitting,esbuild/dce,esbuild/importstar,bundler_barrel,bundler_minify,bundler_bun,bundler_defer,bundler_compile_splitting(1543 pass and 0 fail together),bundler_bytecode_portable(22 pass),bundler_compile -t Bytecode(25 pass), the changed case oftest/aot/code-from-disk.test.ts, andbun run rust:test -p bun_bundler --lib -- inside_wrapper_prefix(2 pass).bundler_bytecode_portableneeds a longer--timeoutwith a debug binary.The 43 new
bundler_edgecasecases on a debug build of main3396aead750: 19 fail because main is wrong, 6 fail because they pin output that differs from main's, 5 pass on both, 13 aretodo. With--todo, each of the 12todocells of the table fails at the assertion on the bundle, after node printed the expected order. 12 more tests run node on the sources of a case. They need node 20 or later and are skipped without it.no test proof · iteration 2 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/bundler/bundler_bytecode_portable.test.ts, test/aot/code-from-disk.test.ts