From 74caa1761738bd982c1fe4c442f4542dd2b55729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Silva?= <15066801+dasilvaluis@users.noreply.github.com> Date: Wed, 21 Oct 2026 14:34:42 +0300 Subject: [PATCH] fix(v10/nitro): Use forward slashes for resolved plugin paths on Windows Backport of: #25023 Co-Authored-By: GPT-6 --- packages/nitro/src/utils/resolver.ts | 5 ++++- packages/nitro/test/resolver.test.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 packages/nitro/test/resolver.test.ts diff --git a/packages/nitro/src/utils/resolver.ts b/packages/nitro/src/utils/resolver.ts index f0bde304d929..0b1f311cef65 100644 --- a/packages/nitro/src/utils/resolver.ts +++ b/packages/nitro/src/utils/resolver.ts @@ -20,6 +20,9 @@ export function createResolver(base: string): Resolver { } return { - resolve: (...path) => resolve(resolvedBase, ...path), + // Nitro writes plugin paths verbatim into a generated `import "…"` statement, where the + // backslashes of a Windows path read as escape sequences (`C:\Users` becomes `C:Users`). + // Forward slashes resolve on every platform, so normalize to them. + resolve: (...path) => resolve(resolvedBase, ...path).replace(/\\/g, '/'), }; } diff --git a/packages/nitro/test/resolver.test.ts b/packages/nitro/test/resolver.test.ts new file mode 100644 index 000000000000..6db133774126 --- /dev/null +++ b/packages/nitro/test/resolver.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from 'vitest'; +import { createResolver } from '../src/utils/resolver'; + +describe('createResolver', () => { + it('resolves relative to the directory of a file URL', () => { + const resolver = createResolver(import.meta.url); + + expect(resolver.resolve('../src/utils/resolver.ts')).toMatch(/packages\/nitro\/src\/utils\/resolver\.ts$/); + }); + + it('never returns backslashes, so the path survives being written into an import string', () => { + const resolver = createResolver(import.meta.url); + + expect(resolver.resolve('../runtime/plugins/server')).not.toContain('\\'); + }); +});