Skip to content

Commit 20520fa

Browse files
authored
fix: simplify debug package resolution (#10374)
1 parent 875197a commit 20520fa

File tree

22 files changed

+241
-157
lines changed

22 files changed

+241
-157
lines changed

.changeset/wild-actors-burn.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@cloudflare/unenv-preset": patch
3+
"wrangler": patch
4+
---
5+
6+
Simplify debug package resolution with nodejs_compat
7+
8+
A patched version of `debug` was previously introduced that resolved the package to a custom implementation. However, this caused issues due to CJS/ESM interop problems. We now resolve the `debug` package to use the Node.js implementation instead.

fixtures/nodejs-hybrid-app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
"devDependencies": {
1111
"@cloudflare/workers-tsconfig": "workspace:*",
1212
"@cloudflare/workers-types": "catalog:default",
13+
"@types/debug": "4.1.12",
1314
"@types/pg": "^8.11.2",
15+
"debug": "4.4.1",
1416
"pg": "8.11.3",
1517
"pg-cloudflare": "^1.1.1",
1618
"undici": "catalog:default",

fixtures/nodejs-hybrid-app/src/index.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export default {
4242
return await testSqlite();
4343
case "/test-http":
4444
return await testHttp();
45+
case "/test-debug-import":
46+
return await testDebugImport();
47+
case "/test-debug-require":
48+
return await testDebugRequire();
4549
}
4650

4751
return new Response(
@@ -55,6 +59,8 @@ export default {
5559
<a href="test-crypto">node:crypto</a>
5660
<a href="test-sqlite">node:sqlite</a>
5761
<a href="test-http">node:http</a>
62+
<a href="test-debug-import">debug (import)</a>
63+
<a href="test-debug-require">debug (require)</a>
5864
`,
5965
{ headers: { "Content-Type": "text/html; charset=utf-8" } }
6066
);
@@ -281,3 +287,67 @@ async function testHttp() {
281287

282288
return new Response("OK");
283289
}
290+
291+
async function testDebugImport() {
292+
const debug = (await import("debug")).default;
293+
const capturedLogs: string[] = [];
294+
295+
// Override debug.log to capture output for verification
296+
debug.log = (...args: string[]) => {
297+
capturedLogs.push(args.join(" "));
298+
};
299+
300+
// Test different namespaces based on DEBUG env var: "example:*,test"
301+
const testNamespace = debug("test"); // Should log (matches "test")
302+
const exampleNamespace = debug("example"); // Should NOT log (doesn't match "example:*")
303+
const exampleFooNamespace = debug("example:foo"); // Should log (matches "example:*")
304+
305+
testNamespace("Test import message 1");
306+
exampleNamespace("Example import message (should not appear)");
307+
exampleFooNamespace("Example foo import message");
308+
309+
if (testNamespace.enabled) {
310+
testNamespace("Test import enabled message");
311+
}
312+
313+
// Strip timestamps from captured logs, keeping namespace and message
314+
// Format: "2025-08-14T20:09:49.769Z test Test import message 1"
315+
const logsWithoutTimestamp = capturedLogs.map((log) => {
316+
const parts = log.split(" ");
317+
return parts.slice(1).join(" "); // Remove timestamp, keep namespace + message
318+
});
319+
320+
return Response.json(logsWithoutTimestamp);
321+
}
322+
323+
async function testDebugRequire() {
324+
const debug = require("debug");
325+
const capturedLogs: string[] = [];
326+
327+
// Override debug.log to capture output for verification
328+
debug.log = (...args: string[]) => {
329+
capturedLogs.push(args.join(" "));
330+
};
331+
332+
// Test different namespaces based on DEBUG env var: "example:*,test"
333+
const testNamespace = debug("test"); // Should log (matches "test")
334+
const exampleNamespace = debug("example"); // Should NOT log (doesn't match "example:*")
335+
const exampleFooNamespace = debug("example:foo"); // Should log (matches "example:*")
336+
337+
testNamespace("Test require message 1");
338+
exampleNamespace("Example require message (should not appear)");
339+
exampleFooNamespace("Example foo require message");
340+
341+
if (testNamespace.enabled) {
342+
testNamespace("Test require enabled message");
343+
}
344+
345+
// Strip timestamps from captured logs, keeping namespace and message
346+
// Format: "2025-08-14T20:09:49.769Z test Test require message 1"
347+
const logsWithoutTimestamp = capturedLogs.map((log) => {
348+
const parts = log.split(" ");
349+
return parts.slice(1).join(" "); // Remove timestamp, keep namespace + message
350+
});
351+
352+
return Response.json(logsWithoutTimestamp);
353+
}

fixtures/nodejs-hybrid-app/tests/index.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,26 @@ describe("nodejs compat", () => {
8989
await expect(response.text()).resolves.toBe("OK");
9090
});
9191

92+
test("debug import", async ({ expect }) => {
93+
const { ip, port } = wrangler;
94+
const response = await fetch(`http://${ip}:${port}/test-debug-import`);
95+
await expect(response.json()).resolves.toEqual([
96+
"test Test import message 1",
97+
"example:foo Example foo import message",
98+
"test Test import enabled message",
99+
]);
100+
});
101+
102+
test("debug require", async ({ expect }) => {
103+
const { ip, port } = wrangler;
104+
const response = await fetch(`http://${ip}:${port}/test-debug-require`);
105+
await expect(response.json()).resolves.toEqual([
106+
"test Test require message 1",
107+
"example:foo Example foo require message",
108+
"test Test require enabled message",
109+
]);
110+
});
111+
92112
test("process.env contains vars", async ({ expect }) => {
93113
const { ip, port } = wrangler;
94114
const response = await fetch(`http://${ip}:${port}/process-env`);

fixtures/nodejs-hybrid-app/wrangler.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616
"DB_NAME": "pfmegrnargs",
1717
"DB_USERNAME": "reader",
1818
"DB_PASSWORD": "NWDMCE5xdipIjRrp",
19+
"DEBUG": "example:*,test",
1920
},
2021
}

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
},
8080
"patchedDependencies": {
8181
"@cloudflare/component-listbox@1.10.6": "patches/@cloudflare__component-listbox@1.10.6.patch",
82-
"debug@4.4.1": "patches/debug@4.4.1.patch",
8382
"pg@8.11.3": "patches/pg@8.11.3.patch",
8483
"toucan-js@3.3.1": "patches/toucan-js@3.3.1.patch",
8584
"toucan-js@4.0.0": "patches/toucan-js@4.0.0.patch",

packages/unenv-preset/build.config.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,9 @@ export default defineBuildConfig({
44
declaration: true,
55
rollup: {
66
cjsBridge: true,
7-
inlineDependencies: true,
8-
resolve: {
9-
exportConditions: ["workerd"],
10-
},
117
},
12-
externals: [/^cloudflare:/],
138
entries: [
149
"src/index",
15-
// Use rollup for debug file to inline the dependency
16-
"src/runtime/npm/debug",
17-
// Use mkdist for the rest to preserve structure
18-
{
19-
input: "src/runtime/",
20-
outDir: "dist/runtime",
21-
format: "esm",
22-
pattern: ["**", "!npm/debug.ts"],
23-
},
10+
{ input: "src/runtime/", outDir: "dist/runtime", format: "esm" },
2411
],
2512
});

packages/unenv-preset/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@
4343
"check:type": "tsc --noEmit"
4444
},
4545
"devDependencies": {
46-
"@types/debug": "4.1.12",
4746
"@types/node-unenv": "npm:@types/node@^22.14.0",
48-
"debug": "4.4.1",
4947
"typescript": "catalog:default",
5048
"unbuild": "^3.2.0"
5149
},

packages/unenv-preset/src/preset.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,6 @@ export function getCloudflarePreset({
110110
[`node:${m}`, `@cloudflare/unenv-preset/node/${m}`],
111111
])
112112
),
113-
114-
// To override the npm shim from unenv
115-
debug: "@cloudflare/unenv-preset/npm/debug",
116113
},
117114
inject: {
118115
// Setting symbols implemented by workerd to `false` so that `inject`s defined in base presets are not used.

packages/unenv-preset/src/runtime/npm/debug.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)