Skip to content

Commit 82a279c

Browse files
dasilvaluisclaude
andcommitted
fix(nitro): Use forward slashes for resolved plugin paths on Windows
`createResolver` returned `node:path` results, so on Windows the server plugin was registered as `C:\Users\...\runtime\plugins\server`. Nitro writes plugin paths verbatim into the generated `#nitro/virtual/plugins` module (`import _x from "<path>"`), where the backslashes are read as escape sequences, so the import becomes `C:Users...` and both `vite dev` and `vite build` fail with ERR_MODULE_NOT_FOUND / "failed to resolve import". Nitro's own plugin paths come from `pathe` and are unaffected. Normalize the resolved path to forward slashes, which resolve on every platform. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent ec4931e commit 82a279c

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

‎packages/nitro/src/utils/resolver.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ export function createResolver(base: string): Resolver {
2020
}
2121

2222
return {
23-
resolve: (...path) => resolve(resolvedBase, ...path),
23+
// Nitro writes plugin paths verbatim into a generated `import "…"` statement, where the
24+
// backslashes of a Windows path read as escape sequences (`C:\Users` becomes `C:Users`).
25+
// Forward slashes resolve on every platform, so normalize to them.
26+
resolve: (...path) => resolve(resolvedBase, ...path).replace(/\\/g, '/'),
2427
};
2528
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { createResolver } from '../src/utils/resolver';
3+
4+
describe('createResolver', () => {
5+
it('resolves relative to the directory of a file URL', () => {
6+
const resolver = createResolver(import.meta.url);
7+
8+
expect(resolver.resolve('../src/utils/resolver.ts')).toMatch(/packages\/nitro\/src\/utils\/resolver\.ts$/);
9+
});
10+
11+
it('never returns backslashes, so the path survives being written into an import string', () => {
12+
const resolver = createResolver(import.meta.url);
13+
14+
expect(resolver.resolve('../runtime/plugins/server')).not.toContain('\\');
15+
});
16+
});

0 commit comments

Comments
 (0)