From a636adaf74ce2400aeb79c35eeab794f9242f138 Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:42:07 +0000 Subject: [PATCH 1/5] test: a Windows working directory spelled with the `\\?\` prefix Windows-only tests for a process that starts in, or changes into, a directory spelled `\\?\C:\dir` or `\\?\UNC\server\share\dir`: - `bun -e`, `--preload`, `--cwd`, `bun run ` and `bun test` name every path from the plain spelling of the directory. - `process.chdir()` into each spelling gives the plain `process.cwd()`. - `bun build --app` builds. Each case also runs from the plain spelling, as a control. The cases with the prefix fail until the working directory readers drop it. Co-authored-by: Dylan Conway --- test/bake/dev/production.test.ts | 59 ++++++++--- test/js/node/process/process.test.js | 148 +++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 17 deletions(-) diff --git a/test/bake/dev/production.test.ts b/test/bake/dev/production.test.ts index 6771c0f96261..c5400b945591 100644 --- a/test/bake/dev/production.test.ts +++ b/test/bake/dev/production.test.ts @@ -456,24 +456,27 @@ export default function () { expect(exitCode).toBe(1); }); + // A framework without dependencies. The page is "homepage" and names the chunk of the client entry point. + const customFramework = { + "client.ts": `console.log("client loaded");`, + "server.ts": ` + export function render(req, meta) { + return new Response(String(meta.pageModule.default())); + } + export async function prerender(meta) { + const scripts = meta.modules.map(m => '').join(""); + return { files: { "index.html": "" + meta.pageModule.default() + scripts + "" } }; + } + `, + "routes/index.ts": `export default () => "homepage";`, + "app.ts": ` + const fsr = { root: "routes", style: "nextjs-pages", serverEntryPoint: "./server.ts", clientEntryPoint: "./client.ts" }; + export default { app: { framework: { fileSystemRouterTypes: [fsr] } } }; + `, + }; + test("builds a framework without server components and keeps its client entry point", async () => { - using dir = tempDir("bake-production-custom-framework", { - "client.ts": `console.log("client loaded");`, - "server.ts": ` - export function render(req, meta) { - return new Response(String(meta.pageModule.default())); - } - export async function prerender(meta) { - const scripts = meta.modules.map(m => '').join(""); - return { files: { "index.html": "" + meta.pageModule.default() + scripts + "" } }; - } - `, - "routes/index.ts": `export default () => "homepage";`, - "app.ts": ` - const fsr = { root: "routes", style: "nextjs-pages", serverEntryPoint: "./server.ts", clientEntryPoint: "./client.ts" }; - export default { app: { framework: { fileSystemRouterTypes: [fsr] } } }; - `, - }); + using dir = tempDir("bake-production-custom-framework", customFramework); const { exitCode, stderr } = await Bun.$`${bunExe()} build --app ./app.ts` .cwd(String(dir)) @@ -489,6 +492,28 @@ export default function () { expect(exitCode).toBe(0); }); + // Windows keeps a `\\?\` prefix in the working directory of a process that starts in a directory spelled with one. + test.skipIf(!isWindows)("builds from a working directory spelled with the \\\\?\\ prefix", async () => { + using dir = tempDir("bake-production-verbatim-cwd", customFramework); + + await using proc = Bun.spawn({ + cmd: [bunExe(), "build", "--app", "./app.ts"], + env: bunEnv, + cwd: "\\\\?\\" + String(dir), + stdout: "ignore", + stderr: "pipe", + }); + const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]); + const html = await Bun.file(path.join(String(dir), "dist", "index.html")) + .text() + .catch(() => stderr); + expect(html).toContain("homepage"); + const script = html.match(/').join(""); - return { files: { "index.html": "" + meta.pageModule.default() + scripts + "" } }; - } - `, - "routes/index.ts": `export default () => "homepage";`, - "app.ts": ` - const fsr = { root: "routes", style: "nextjs-pages", serverEntryPoint: "./server.ts", clientEntryPoint: "./client.ts" }; - export default { app: { framework: { fileSystemRouterTypes: [fsr] } } }; - `, - }; - test("builds a framework without server components and keeps its client entry point", async () => { - using dir = tempDir("bake-production-custom-framework", customFramework); + using dir = tempDir("bake-production-custom-framework", { + "client.ts": `console.log("client loaded");`, + "server.ts": ` + export function render(req, meta) { + return new Response(String(meta.pageModule.default())); + } + export async function prerender(meta) { + const scripts = meta.modules.map(m => '').join(""); + return { files: { "index.html": "" + meta.pageModule.default() + scripts + "" } }; + } + `, + "routes/index.ts": `export default () => "homepage";`, + "app.ts": ` + const fsr = { root: "routes", style: "nextjs-pages", serverEntryPoint: "./server.ts", clientEntryPoint: "./client.ts" }; + export default { app: { framework: { fileSystemRouterTypes: [fsr] } } }; + `, + }); const { exitCode, stderr } = await Bun.$`${bunExe()} build --app ./app.ts` .cwd(String(dir)) @@ -493,8 +490,23 @@ export default function () { }); // Windows keeps a `\\?\` prefix in the working directory of a process that starts in a directory spelled with one. + // https://github.com/oven-sh/bun/issues/11953 test.skipIf(!isWindows)("builds from a working directory spelled with the \\\\?\\ prefix", async () => { - using dir = tempDir("bake-production-verbatim-cwd", customFramework); + using dir = tempDir("bake-production-verbatim-cwd", { + "server.ts": ` + export function render() { + return new Response(""); + } + export async function prerender(meta) { + return { files: { "index.html": meta.pageModule.default() } }; + } + `, + "routes/index.ts": `export default () => "homepage";`, + "app.ts": ` + const fsr = { root: "routes", style: "nextjs-pages", serverEntryPoint: "./server.ts" }; + export default { app: { framework: { fileSystemRouterTypes: [fsr] } } }; + `, + }); await using proc = Bun.spawn({ cmd: [bunExe(), "build", "--app", "./app.ts"], @@ -504,14 +516,10 @@ export default function () { stderr: "pipe", }); const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]); - const html = await Bun.file(path.join(String(dir), "dist", "index.html")) + const page = await Bun.file(path.join(String(dir), "dist", "index.html")) .text() - .catch(() => stderr); - expect(html).toContain("homepage"); - const script = html.match(/