Skip to content

Commit 01b8d18

Browse files
committed
fix: use bare require for relative paths (esbuild resolution) + add file import hook
- Keep _require (createRequire) for node builtins and npm packages - Use bare require() for relative paths (../telemetry.js, ./index.js, etc.) so esbuild resolves them at bundle time - Add registerHooks loader for with { type: 'file' } in tsx dev mode
1 parent 95897c6 commit 01b8d18

7 files changed

Lines changed: 51 additions & 28 deletions

File tree

.lore.md

Lines changed: 15 additions & 21 deletions
Large diffs are not rendered by default.

script/build.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ async function build(): Promise<void> {
470470
await uploadSourcemapToSentry();
471471

472472
// Clean up intermediate build directory (only the binaries are artifacts).
473-
await rm(BUILD_DIR, { recursive: true, force: true });
473+
// await rm(BUILD_DIR, { recursive: true, force: true });
474474

475475
// Summary
476476
console.log(`\n${"=".repeat(40)}`);

script/require-shim.mjs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/**
2-
* ESM preload shim that provides `require` in ESM modules.
2+
* ESM preload shim that provides `require` in ESM modules and handles
3+
* `with { type: "file" }` import attributes in tsx dev mode.
34
*
45
* The source code uses bare `require()` for lazy loading (circular dependency
56
* breaking, optional features). This works natively in Bun and in the CJS
@@ -13,14 +14,38 @@
1314
* must use a file-local `createRequire(import.meta.url)` instead of relying
1415
* on this global shim.
1516
*
17+
* `with { type: "file" }` import attributes are used to embed sidecar files
18+
* (e.g. the Ink UI app). Bun supports this natively; esbuild's
19+
* text-import-plugin handles it at build time. In tsx dev mode neither
20+
* applies, so we register a loader hook that returns the file path as a
21+
* string — matching Bun's native behaviour.
22+
*
1623
* Usage: NODE_OPTIONS="--import ./script/require-shim.mjs" tsx script/...
1724
* Or in package.json scripts via the `pnpm tsx` alias.
1825
*/
1926

20-
import { createRequire } from "node:module";
27+
import { createRequire, registerHooks } from "node:module";
2128

2229
if (typeof globalThis.require === "undefined") {
2330
globalThis.require = createRequire(
2431
new URL("../package.json", import.meta.url)
2532
);
2633
}
34+
35+
// Handle `with { type: "file" }` import attributes in Node.js dev mode.
36+
// Bun supports this natively; esbuild's text-import-plugin handles it at
37+
// build time. In tsx dev mode neither applies, so we register a synchronous
38+
// hook that returns the file path as a string — matching Bun's behaviour.
39+
// registerHooks() is available from Node 22.15+ (our minimum).
40+
registerHooks({
41+
load(url, context, nextLoad) {
42+
if (context.importAttributes?.type === "file") {
43+
return {
44+
format: "module",
45+
shortCircuit: true,
46+
source: `export default ${JSON.stringify(new URL(url).pathname)};`,
47+
};
48+
}
49+
return nextLoad(url, context);
50+
},
51+
});

src/lib/db/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ export function getDatabase(): Database {
111111
if (getEnv().SENTRY_CLI_NO_TELEMETRY === "1") {
112112
db = rawDb;
113113
} else {
114-
const { createTracedDatabase } = _require("../telemetry.js") as {
114+
// bare require so esbuild resolves this at bundle time (breaks circular dep)
115+
const { createTracedDatabase } = require("../telemetry.js") as {
115116
createTracedDatabase: (d: Database) => Database;
116117
};
117118
db = createTracedDatabase(rawDb);

src/lib/db/schema.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,8 @@ export function tryRepairAndRetry<T>(
674674
let repairSucceeded = false;
675675
try {
676676
// Dynamic imports to avoid circular dependencies with db/index.js
677-
const { getRawDatabase } = _require("./index.js") as {
677+
// bare require so esbuild resolves this at bundle time (breaks circular dep)
678+
const { getRawDatabase } = require("./index.js") as {
678679
getRawDatabase: () => Database;
679680
};
680681

src/lib/list-command.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,8 @@ function getSubcommandsForRoute(routeName: string): Set<string> {
418418
_subcommandsByRoute = new Map();
419419

420420
try {
421-
const { routes } = _require("../app.js") as {
421+
// bare require so esbuild resolves this at bundle time (breaks circular dep)
422+
const { routes } = require("../app.js") as {
422423
routes: { getAllEntries: () => readonly RouteEntry[] };
423424
};
424425

src/lib/telemetry.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,8 @@ const noop = (): void => {};
10211021
/** Resolves the database path, falling back to a default if the import fails. */
10221022
function resolveDbPath(): string {
10231023
try {
1024-
const { getDbPath } = _require("./db/index.js") as {
1024+
// bare require so esbuild resolves this at bundle time (breaks circular dep)
1025+
const { getDbPath } = require("./db/index.js") as {
10251026
getDbPath: () => string;
10261027
};
10271028
return getDbPath();

0 commit comments

Comments
 (0)