Repository navigation
Conversation
…JS and dev-server output `bun build --target=bun` writes `require` as `var __require = import.meta.require;`. A second build over such a file for node, or as CommonJS, left that line as written: `TypeError: __require is not a function` under node, and `SyntaxError: import.meta is only valid inside modules` as CommonJS. The `EImportMeta` arm now returns `E::Special::ImportMetaRequire` for a file for Bun or node in CommonJS output, in an ES module of a build for node, and on the dev server. The printer spells the node like `ERequireCallTarget`: `require`, the `__require` of the runtime, `hmr.require`. ES-module output for Bun, iife output and files for the browser keep `import.meta.require`. The module that the sqlite loader writes calls `require` in CommonJS output. Co-authored-by: chloe caruso <git@paperclover.net>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 18 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Updated 5:05 AM PT - Oct 21st, 2026
❌ @robobun, your commit cfc0e92 has some failures in 🧪 To try this PR locally: bunx bun-pr 46299That installs a local version of the PR into your bun-46299 --bun |
|
Status: ready for review. Reproduced on main at 9b4284f with the two-step reproduction from the reopening comment of #9416: |
| if name == b"require" | ||
| && p.options.lower_import_meta_require | ||
| && !p.method_call_must_be_replaced_with_undefined | ||
| && !p.is_revisit_for_substitution | ||
| && identifier_opts.assign_target() == js_ast::AssignTarget::None | ||
| && !identifier_opts.is_delete_target() | ||
| { | ||
| if p.options.features.allow_runtime { | ||
| p.record_usage_of_runtime_require(); | ||
| } | ||
| return Some(Expr { | ||
| data: js_ast::ExprData::ESpecial(E::Special::ImportMetaRequire), | ||
| loc: target.loc, | ||
| }); | ||
| } |
There was a problem hiding this comment.
🔴 Users who bundle for node code that detects Bun by testing import.meta.require now get a startup crash instead of the non-Bun branch. The arm at src/js_parser/fold.rs:616 lowers every non-assigned read, so import.meta.require ? import.meta.require("bun:sqlite") : null or typeof import.meta.require === "function" becomes a test of __require, which is always truthy in node output, and the guarded call then throws. Fix: keep the value undefined where the base did in positions that only test it (typeof, !, ? :, ??, ||, &&, == null) while still lowering calls, .resolve and plain value reads so const r = import.meta.require; r("x") keeps working. [also at: src/bundler/ParseTask.rs:2710 - Node-target bundles of code that feature-detects Bun with import.meta.require now take the Bun branch under node and throw, where on the base they fell back.]
Why this was flagged
A dependency or source file contains const sqlite = import.meta.require ? import.meta.require("bun:sqlite") : null; or if (typeof import.meta.require === "function") { ... Bun-only path ... } and is bundled with bun build --target=node (ESM or CJS) or --target=bun --format=cjs. src/bundler/ParseTask.rs:2702-2710 sets lower_import_meta_require for those outputs; src/js_parser/fold.rs:616-630 then replaces the read with E::Special::ImportMetaRequire for every position except assignment and delete targets, and src/js_printer/lib.rs:3423 prints it as __require or require. Under node the test is now true and the guarded __require("bun:sqlite") throws Cannot find module 'bun:sqlite' at module load. On the base branch the same output printed import.meta.require unchanged, which is undefined under node, so the test was false and the non-Bun branch ran. The PR's own test at test/bundler/bundler_bun.test.ts:443 (tested() expects "has require") records this change for an ordinary input.
Verification: src/js_parser/fold.rs:616-630 replaces every non-assigned, non-deleted read of import.meta.require with E::Special::ImportMetaRequire when lower_import_meta_require is set. On the base commit the EImportMeta arm left the access as written, so node evaluated import.meta.require to undefined and took the non-Bun branch; this is a regression that works on the base.
| true, | ||
| ); | ||
| } | ||
| E::Special::ImportMetaRequire => { | ||
| self.print_expr( | ||
| Expr { | ||
| data: ExprData::ERequireCallTarget, | ||
| loc: expr.loc, | ||
| }, | ||
| level, |
There was a problem hiding this comment.
🟡 (optional) Dev-server client code that stores import.meta.require in a variable before calling it loses HMR dependency tracking, so edits to the required file now force a full page reload. The node prints as hmr.require (src/js_printer/lib.rs:3565), a prototype method whose this is the importer; called unbound, loadModuleSync gets importer === undefined and never records the edge (src/runtime/bake/hmr-module.ts:147, 307). On the base the client printed hmr.importMeta.require, which is this.require.bind(this) (hmr-module.ts:179). Fix: make the value safe to call detached for both require and import.meta.require, e.g. bind require per instance in the HMRModule constructor or print hmr.require.bind(hmr) when ERequireCallTarget is not the call target.
Why this was flagged
A dev-server client module contains const load = import.meta.require; const dep = load("./dep.js");. With output format InternalBakeDev, src/js_parser/fold.rs:616-629 returns E::Special::ImportMetaRequire, and src/js_printer/lib.rs:3420-3429 prints it through ERequireCallTarget, which for InternalBakeDev emits hmr.require (src/js_printer/lib.rs:3565-3567). HMRModule.prototype.require (src/runtime/bake/hmr-module.ts:145-147) calls loadModuleSync(id, true, this); invoked detached from load, this is undefined, so if (importer) mod.importers.add(importer) at hmr-module.ts:307-308 and 330-331 is skipped. When ./dep.js is edited, the hot-update walk at hmr-module.ts:676-679 sees importers.size === 0 without a self-accept, records a failure and does a full reload with the "root module that does not self-accept" message instead of propagating to the importer's import.meta.hot.accept. On the base branch the same source printed hmr.importMeta.require (src/js_printer/lib.rs:3282-3285), which is this.require.bind(this) at hmr-module.ts:179, so the importer edge was recorded.
Verification: HMRModule.prototype.require (hmr-module.ts:145-148) calls loadModuleSync(id, true, this); as a class method it runs in strict mode, so an unbound call passes importer === undefined. Every mod.importers.add(importer) site is guarded by if (importer) (hmr-module.ts:307, 330, 369, 418, 444, 481), so the call succeeds silently but records no edge.
| // The printer spells this node as the `require` of the output. `--drop` of it needs the `E::Dot`. A revisit cannot record the use of the runtime's `__require`. | ||
| if name == b"require" | ||
| && p.options.lower_import_meta_require | ||
| && !p.method_call_must_be_replaced_with_undefined |
There was a problem hiding this comment.
🟡 (optional) Node-target builds of code that reads an import.meta.hot method without calling it leave the next import.meta.require unlowered, so it is undefined under node while the same expression a line earlier is a function. The guard at src/js_parser/fold.rs:618 reads method_call_must_be_replaced_with_undefined, which src/js_parser/fold.rs:782 and :816 set for every non-HMR import.meta.hot.<method> access and which only the next call visit clears (src/js_parser/visit/visit_expr.rs:2127). Fix: the --drop check must look at the current expression (e.g. compare the define hit or check the dot is the call target) instead of the sticky parser flag, so a stale flag from a sibling expression cannot suppress lowering.
Why this was flagged
A production (non-HMR) build for node contains, e.g., const dispose = import.meta.hot.dispose; const load = import.meta.require; (Vite-style modules read import.meta.hot methods as values). At src/js_parser/fold.rs:816 the hot method access sets p.method_call_must_be_replaced_with_undefined = true and returns undefined; the flag is only reset inside the next ECall visit at src/js_parser/visit/visit_expr.rs:2124-2127. The import.meta.require read that follows is not a call, so when it reaches the arm at src/js_parser/fold.rs:618 the flag is still set, the guard skips lowering and the dot is printed as import.meta.require, which is undefined under node. The dismissal only checked that drop cannot be defeated; it did not check that the guard's own action, suppressing the lowering, is the user-visible failure when the flag is stale. The author acknowledges this window in the PR notes but ships no test for it and bun/ImportMetaRequireAfterImportMetaHot only covers the call form. Remedy: gate on a per-expression drop decision rather than the sticky flag.
Verification: src/js_parser/fold.rs:782 and :816 set p.method_call_must_be_replaced_with_undefined = true unconditionally. src/js_parser/fold.rs:616-622 requires the flag clear, so an import.meta.require read after a non-call hot-method read is printed as written, undefined under node. On the base branch import.meta.require is never lowered for node, so this input already yields undefined there.
| opts.lower_import_meta_require = match output_format { | ||
| options::Format::InternalBakeDev => true, | ||
| options::Format::Iife => false, | ||
| options::Format::Cjs => target.is_server_side(), |
There was a problem hiding this comment.
🟣 pre-existing, not blocking: pre-existing: users of bun build --format=cjs with no --target still get CommonJS output that contains import.meta.require, which is a SyntaxError in every CommonJS loader (node, webpack). The gate at src/bundler/ParseTask.rs:2705 is target.is_server_side(), so a browser-target CJS build is left unlowered. The stated reason for excluding the browser (a module script has no require) only holds for ESM output; a CJS module always has require and never has import.meta. Fix: lower import.meta.require to require for every CJS output regardless of target (Format::Cjs => true), keeping the HTML client files of a server build untouched, which already come through an ESM transpiler.
A small fix can ride a push you are already making; otherwise a short reply is enough.
Why this was flagged
A library or a dependency it bundles contains typeof Bun !== "undefined" ? import.meta.require("x") : null, or is a file that bun build --target=bun wrote (var __require = import.meta.require;). The user runs bun build --format=cjs entry.js with no --target, so target at src/bundler/ParseTask.rs:2479 is Target::Browser. The match at src/bundler/ParseTask.rs:2705 gives lower_import_meta_require = false, so the E::Dot arm at src/js_parser/fold.rs:616 does not fire and the output keeps import.meta.require. Loading that CommonJS file in node or any bundler throws SyntaxError: Cannot use 'import.meta' outside a module. The base branch produces the same broken output, so this is pre-existing; the PR lowers the same spelling for --target=bun and --target=node CJS output at the same line, and the printer path at src/js_printer/lib.rs:3559 already prints the bare global require for Format::Cjs, so the same lowering would be correct for browser-target CJS too.
Verification: bun build --format=cjs entry.js with no --target defaults to Target::Browser. src/bundler/ParseTask.rs:2702-2710 sets options::Format::Cjs => target.is_server_side(), which is false for Target::Browser, so the fold at src/js_parser/fold.rs:616-630 does not fire. Node's CommonJS loader rejects import.meta with a SyntaxError, so the CJS output fails to load at all.
| } | ||
|
|
||
| // The printer spells this node as the `require` of the output. `--drop` of it needs the `E::Dot`. A revisit cannot record the use of the runtime's `__require`. | ||
| if name == b"require" |
There was a problem hiding this comment.
🟣 pre-existing, not blocking: Users who build import.meta["require"](...) for node or as cjs get a bundle that works unminified and crashes with --minify-syntax. The new arm at src/js_parser/fold.rs:616 only runs from the EDot visit; with minify the EIndex path at src/js_parser/visit/visit_expr.rs:995-1016 rewrites the index to a dot and returns without running the fold, so the minified output keeps import.meta.require (undefined under node, SyntaxError in the @ bun-cjs wrapper) while the unminified output prints __require/require. Fix: lower every spelling that the lowering claims, e.g. run the import.meta fold (or re-visit the new EDot) after the EIndex->EDot shortcut so import.meta["require"], ["main"] and ["hot"] match the dotted form in both minify states.
A small fix can ride a push you are already making; otherwise a short reply is enough.
Why this was flagged
Trigger: source containing import.meta["require"] bundled with --target=node (esm or cjs) or --format=cjs --target=bun, with --minify-syntax or --minify. In visit_expr.rs:995-1016 the EIndex is turned into an E::Dot and the visitor returns at line 1016 without calling the property-access fold, so fold.rs:616-629 never sees it and no ESpecial::ImportMetaRequire is produced; record_usage_of_runtime_require is also not called. The same source without minify goes through visit_expr.rs:1023 onward and is lowered. Result: unminified node output runs, minified node output throws TypeError: import.meta.require is not a function, and minified cjs output is a SyntaxError inside the wrapper. On base both minify states were identical (both left as written), so the PR introduces a minify/non-minify divergence, the semantics-changing-minify bug class. Remedy: make the EIndex->EDot shortcut fall through into the same property-access fold the EDot path uses.
Verification: With minify, src/js_parser/visit/visit_expr.rs:995-1016 builds an E::Dot, assigns *e = dot; and returns; maybe_rewrite_property_access is never reached, so no ImportMetaRequire node is produced. Without minify, visit_expr.rs:1023-1039 reaches the fold at src/js_parser/fold.rs:597-630 and prints __require/require. No test uses import.meta["require"].
| if name == b"require" | ||
| && p.options.lower_import_meta_require | ||
| && !p.method_call_must_be_replaced_with_undefined | ||
| && !p.is_revisit_for_substitution |
There was a problem hiding this comment.
🟣 pre-existing, not blocking: Users bundling for node with --minify-syntax get undefined for import.meta.require reached through a local alias of import.meta, while the direct spelling in the same file prints __require. The guard !p.is_revisit_for_substitution at src/js_parser/fold.rs:619 skips the lowering when const m = import.meta; m.require || null is re-visited after inlining (src/js_parser/p.rs:2748-2754), and substitutions whose result is a call never re-run the fold at all (src/js_parser/p.rs:2755-2757), so import.meta.require(...) is emitted verbatim and throws under node. Fix: lower the alias form consistently with the direct form, and record the __require runtime usage at substitution time instead of relying on the revisit.
A small fix can ride a push you are already making; otherwise a short reply is enough.
Why this was flagged
Trigger: const m = import.meta; return m.require("x") or m.require || null in a file bundled with --target=node (esm or cjs) and --minify-syntax. The single-use-symbol substitution at p.rs:2735 replaces m with import.meta; when the result is EBinary/EUnary/EIf the revisit runs with is_revisit_for_substitution = true (p.rs:2749) and fold.rs:619 bails; when the result is an ECall no revisit happens (p.rs:2755-2757), so the fold never sees the new import.meta.require E::Dot. The printed output is import.meta.require(...), which is undefined under node (TypeError) and a SyntaxError inside the cjs wrapper, while a sibling direct import.meta.require("x") in the same file is lowered to __require("x"). Remedy: lower at substitution time or block the substitution for .require so both forms agree.
Verification: The new arm at src/js_parser/fold.rs:616-630 bails on !p.is_revisit_for_substitution (line 619); when the result is an ECall there is no revisit at all (p.rs:2755-2757), so the fold never sees the new import.meta.require. The aliased access prints import.meta.require while the direct spelling in the same file prints __require.
Fixes #9416
Problem
bun buildover a file thatbun build --target=bunwrote exits 0, and the output fails at start:TypeError: __require is not a function(for node),SyntaxError: import.meta is only valid inside modules(as cjs).requirethere asvar __require = import.meta.require;(src/bundler/ParseTask.rs:422). TheEImportMetaarm (src/js_parser/fold.rs:597) leaves it as written for every output.Fix
E::Special::ImportMetaRequire, in CommonJS output for Bun or node, in ES-module output for node, and on the dev server. The printer spells it as that output'srequire:require,__require,hmr.require.require: nothing is resolved at build time.requirein CommonJS output (bundler: use require() for embedded sqlite modules in cjs output #38173).test/bundler/bundler_bun.test.ts(54 new tests, 43 fail on main),dev-and-prod.test.ts,react-compiler.test.ts, and all oftest/bundler/. Self-reviewed: 23 concerns raised, 22 addressed (Notes).Background
import.meta.requireis Bun'srequirefor an ES module. Node has none. CommonJS has noimport.meta.__requireis therequireof a bundle:createRequire(import.meta.url)in a build for node.requirenode (Make import.meta.require act as e_require_ref #14279, bundler: lower import.meta.require for non-bun targets #35662): it resolves.resolve("x")and guarded calls at build time.Downsides
import.meta.requirenow finds Bun, andimport.meta.require("bun:sqlite")behind it throws.--define import.meta.require=undefinedgives the old value.requireran on main when node loaded it as an ES module ("type": "module"). It throws now. Notes have two more shapes.import.meta.x.Notes
The reports, each run on main (9b4284f) and on this branch
What changes, by output
import.meta.requireprints asimport.meta.require(no change)--bytecode)require__require, which iscreateRequire(import.meta.url)requireimport.meta.require(no change)hmr.requireimport.meta.require(no change: iife output has no__requirefor a value, #38077)bun buildwith bundling.--no-bundleandBun.Transpilerdo not change.ParseTask.rs. In CommonJS output the target of the file decides: a file for Bun or node hasrequire. In an ES module the target of the build decides as well: the__requireof a bundle iscreateRequireonly in a build for node. The parser puts the node in place ofimport.meta.requirewhen it is not assigned and not deleted.import.meta?.requireandconst { require } = import.metaare other forms. They stay as written.#!/usr/bin/env bunhas Bun as its target in every build on main (target_from_hashbang, which bundler: apply an explicit target to a bun hashbang entry point #38598 changes). In a build with no--targetits ES-module output does not change, and its CommonJS output is lowered: that chunk is Bun's CommonJS wrapper. In a build for node it is lowered like its dependencies, so ES-module output of a command-line tool that Bun built runs under node as the first entry too.--defineor a--dropof the dottedimport.meta.requirewins. A define reaches theimport.meta["require"]spelling only with--minify-syntax, as for every define on main.__requireof the bundle goes with it. A nested statementimport.meta.require;prints as__require;and keeps thecreateRequireline, as a nestedrequire;does. On main that statement is removed.__requireis recorded with the node, as forrequire.--minify-syntaxcan putimport.metain place of a name and visit the access again (const m = import.meta; return m.require || null). That visit cannot record a use. The access stays onimport.metathere, as in the build that is not minified.import.meta.hotmethod that is not a call (const on = import.meta.hot.on), main leaves the parser flag for dropped calls set until the next call (js_parser: set the import.meta.hot call-drop flag only for a call target #36875). The arm reads that flag for--drop. Animport.meta.requirein that window stays as written.import.meta.require(path, { type: "sqlite" }).dbwith no visit pass. In CommonJS output it now builds the call onrequire. That is the arm of bundler: use require() for embedded sqlite modules in cjs output #38173.Dev server
TODOintest/bake/dev-and-prod.test.tsasked forhmr.require. The value is thehmr.requirethatrequiregives there. Before, it was a function bound to the module.import.metaprints ashmr.importMeta. That getter readslocationsince fix import.meta.url in hmr #21386 and throwsReferenceError: location is not defined. The dottedimport.meta.requiredoes not go through the getter now. Every other form (typeof import.meta,const { require } = import.meta,import.meta.env) still throws. This change does not repair the getter.hmr.require(name)knows registered modules only.import.meta.require("node:path")in a route fails at the call withFailed to resolve dynamic import 'node:path'.What does not change
--target, apart from an entry with the Bun hashbang, and the browser files of a build for Bun or node (an HTML import, HTML imports:--target=bun/--compilebundles the entry's client scripts for the bun target, folding esbuild'stypeof requireguard into a barerequire(ReferenceError in the browser) #45227 and bundler: give the browser side of a server build its own copy of the runtime #38376). Such a file can end in a module script, which has norequire. Code that testsimport.meta.requirebefore it takes another path takes that path, as on main.--reject-unresolveddoes not look atimport.meta.require(name), as on main.Behaviour changes for hand-written code in output for node, and in cjs output for Bun
import.meta.requireis therequireof the output at run time.typeofgives"function"and a truthiness test passes. Under node on main it wasundefined.import.meta.require("x"),.resolve("x")and.mainreadrequireat run time. No string is resolved or bundled at build time.import.meta.requireand adeleteof it stay onimport.meta. A call after such an assignment callsrequire.import.meta.requireanywhere, also behind a test for Bun, starts withimport { createRequire } from "node:module"andcreateRequire(import.meta.url), as for arequire()there. A guarded call alone grows the output from 120 B to 220 B. A module that is loaded from adata:URL throws on that line (The argument 'filename' must be a file URL object).--define import.meta.require=undefinedgives the value of main, for the whole build.Output that ran on main and throws now
import.meta.requireto find Bun.import.meta.require ? import.meta.require("bun:sqlite") : othertook the other path under node and now throwsCannot find module 'bun:sqlite'. The same test beforeawait import(name)of a module with top-level await givesERR_REQUIRE_ASYNC_MODULE..jsfile under"type": "module", a.mjsname, or a.jsfile that keeps another member ofimport.meta(Node 20.19, 22.7 and later detect the syntax). On main such a file ran when it had norequire, no export and no external import, andimport.meta.requirewasundefined. NowrequirethrowsReferenceError: require is not defined in ES module scope. As.cjsor with"type": "commonjs", a file that keeps another member ofimport.metais aSyntaxErroron main and here (bundler: lower import.meta to a per-file object in cjs and iife output #38200, bundler: pass the real import.meta to cjs output for the bun target #39715).--splitting --target=nodewhen the shared chunk is not in the directory of the entry (entries in two directories, or--chunk-namingwith a directory). When two entries use the__requireof the bundle, it is in the shared chunk, and a relative name inrequire(name)resolves from there. That is so on main for two entries withrequire(name). An entry whose only use isimport.meta.requireis now a user too.import.meta.require. The runtime's__requireis then in use, and the browser chunk getsimport { createRequire } from "node:module"when it uses any runtime helper. Main does this when the server side has arequire(name)that stays for run time (HTML imports:--target=bun/--compilebundles the entry's client scripts for the bun target, folding esbuild'stypeof requireguard into a barerequire(ReferenceError in the browser) #45227, bundler: give the browser side of a server build its own copy of the runtime #38376, bundler: give the browser side of a server build its own runtime module #46272).Output that fails in another way now
eval, and a local that is namedrequire:const require = import.meta.require ?? nullprintsconst require = require ?? null, which throwsCannot access 'require' before initialization. A directevalstops the rename of the local (js_printer: fix require("bun") and other printer literals being captured by same-named locals #35739 is about names of the printer that a local captures). As CommonJS that file is aSyntaxErroron main.--target=node --format=cjswith a#!/usr/bin/env bunentry gives Bun's CommonJS wrapper, which node does not call (bundler: gate @bun pragma and @bun-cjs wrapper on build target, not entry hashbang #33859). A file withimport.meta.requirewas aSyntaxErrorunder node there. Now node exits 0 with no output, as for a file without it.Not in this change
import.meta.require("./x-<hash>.js"), the call that--splitting --target=bunwrites, stays a lookup at run time with the path that Bun wrote. A cjs app over such output now starts, and fails at the first lazy call withCannot find module './x-<hash>.js', as ES-module output for Bun does on main. The reader is a later PR on top of this one.var {require}=import.meta;, the line ofbun build --no-bundle --target=bunandBun.Transpiler. It is a pattern, notimport.meta.require. The reader covers it.var __require = createRequire(import.meta.url), the helper for node (bundler: bundle require() calls made through createRequire(import.meta.url) bindings #36565).import.meta.Fixes #9416is for the reproduction in its reopening comment.dir,fileandpathunder node are Bundlingtarget=nodeshould define __dirname, __filename, import.meta.dir, etc #2865. In cjs,envisimport.meta.envcauses a crypticTypeErrorinbun build --compile#21097,filenameis bundler: fold import.meta.filename for cjs output; emit direct-eval build note #35961, and bundler: lower import.meta to a per-file object in cjs and iife output #38200 and bundler: pass the real import.meta to cjs output for the bun target #39715 cover the rest.import.metato cjs output for Bun. If bundler: lower import.meta to a per-file object in cjs and iife output #38200 lands after this change, therequirerule goes into itsmaybe_rewrite_import_meta_propertyand theFormat::Cjsarm stays. Its expectationundefined undefined undefinedbecomesundefined undefined function, andcompile/ImportMetaRequireFallbackBytecodeloses its warning. bundler: pass the real import.meta to cjs output for the bun target #39715 needs no change of the rule.import.meta.require ?? createRequire(import.meta.url)in--bytecodeoutput) builds and printsfunctionhere. The value isrequire, not thecreateRequirefallback.bun/ImportMetaRequireWithFallbackInBytecodeis that program.Workaround on released versions
--define import.meta.require=require. On main it gives the bytes that this change prints for the forms that Bun writes.--banner 'import.meta.require??=(await import("node:module")).createRequire(import.meta.url);'.Measurements (release builds of merge base 9b4284f and of this branch, one toolchain, one machine)
size: text 107,318,912 to 107,319,680 (+768 B). Data and bss are equal. There is no new function. The largest deltas:get_ast+170 B (the sqlite arm),maybe_rewrite_property_access2 x +118 B,run_from_thread_pool+109 B (the rule),NonLocalBinding::name+73 B.import.meta.urlaccess inmaybe_rewrite_property_access(qemu slope, 200 against 400 sites): 85 to 87 instructions. The visitor around it: 220 to 220.require("lit")site: visitor 382 to 382, printer 125 to 125. For each externalrequirerecord in the printer: 107 to 107.visit_expr_in_outon a bundle with norequireand noimport.meta: 168,508 against 168,508 guest instructions (JS), 1,522 against 1,522 (TS).Expr16 B,E::Special8 B, the parserOptions392 B andP4,056 B are unchanged. The newboolis in padding.import.meta.require: mimalloc entries 63,800 / 63,783 / 63,756 on the merge base and 63,773 / 63,764 / 63,741 here.import.meta.require: 0 of 155 bundles differ (52 npm packages, for bun, node and browser, 291.7 MB), and 0 of 199--no-bundleoutputs differ. Of 8 packages that have it, the 16 builds for Bun and for the browser are identical, and 7 of the 8 builds for node differ.--splitting, bun cjs, node cjs and--compile --bytecode, 13 each. The rest needs the reader.Tests
test/bundler/bundler_bun.test.ts: 54 new tests. 43 fail on main. The other 11 pin what must stay as it is: ES-module output for Bun, a build for the browser as esm and as cjs, iife,--define(two),--drop, a value that nothing uses, a name ofimport.metaunder--minify-syntax, a build for Bun with a page, a#!/usr/bin/env bunentry with the default target.__esm, the helper beside a directeval, the inline call of Bun 1.0.0 to 1.1.42) for node as esm and for bun and node as cjs. Three real writers for the same cells..resolve(),typeof, a truthiness test, a folded callee, a call by name under--reject-unresolved, each with and withoutminifySyntax. An assignment, adelete,--splittingwith two entries, a#!/usr/bin/env bunentry as esm for node and as cjs.--compile --bytecode.test/bake/dev-and-prod.test.ts: one expectation changes, and a route pinshmr.requireon the server side.test/bundler/transpiler/react-compiler.test.ts: the compiler keeps the node, and a join of it withmodule.exportskeeps both.TargetBrowser-cjs,InBrowserFileOfServerBuild,InBunHashbangEntryAsCjs,TargetBun#9416andBehindBunHashbangForNode.test/bundler/andtest/bake/on the release builds of main and of this branch: no test fails only here. What fails is a 5 s limit on this machine:bundler_bytecode_portable(2) andnative-plugin(1) on both builds.bundler_splitting,bundler_cjs2esm,bundler_edgecase,bundler_minify,bundler_plugin,test/bake/dev/bundleandtest/bake/dev/esm. Two tests hit a time limit of this machine there and pass on the release build:splitting/FoldingNeverMakesABundleWorse: graph 47andedgecase/DeepImportDiamondDAG.Earlier work
import.meta.requireon therequirepath in this arm for every target. Its author noted "regresses Bun.embeddedFiles test", and it closed unmerged:.resolve()became a build-machine path under--compile. Here ES-module output for Bun does not change, and.resolve()is a lookup at run time in every output.requirenode. This change takes its tests, adds cjs for Bun and the server side of the dev server, leaves a build for the browser as it is, and replaces it.bundler_bun.test.ts, and one test under--compile --bytecode.Self-review
importMetagetter. It throws for every form ofimport.metaon the server side, and the righturlfor a server-side module is a decision for that code. It is its own change.--splittingtest has its two entries in one directory, because the other layout is the defect of the shared__requireon main. Of the twoimport.meta.hotsequences the test pins the one after a call. The one after a read prints what js_parser: set the import.meta.hot call-drop flag only for a call target #36875 changes. There is no test for cjs output beside another member ofimport.meta: no host runs that output.no test proof · iteration 0 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/bundler/transpiler/react-compiler.test.ts, test/bake/dev-and-prod.test.ts