From 807418fa69c8ffee412fee7eeb886cd51a2f5526 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 31 Aug 2023 10:47:01 +0100 Subject: [PATCH] fix(vite-node): check more precisely for root/base paths (#4049) --- packages/vite-node/src/server.ts | 6 +++--- packages/vite-node/src/source-map.ts | 3 ++- packages/vite-node/src/utils.ts | 13 ++++++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/vite-node/src/server.ts b/packages/vite-node/src/server.ts index 5436281119cb..e99f9bf44069 100644 --- a/packages/vite-node/src/server.ts +++ b/packages/vite-node/src/server.ts @@ -6,7 +6,7 @@ import createDebug from 'debug' import type { EncodedSourceMap } from '@jridgewell/trace-mapping' import type { DebuggerOptions, FetchResult, ViteNodeResolveId, ViteNodeServerOptions } from './types' import { shouldExternalize } from './externalize' -import { normalizeModuleId, toArray, toFilePath } from './utils' +import { normalizeModuleId, toArray, toFilePath, withTrailingSlash } from './utils' import { Debugger } from './debug' import { withInlineSourcemap } from './source-map' @@ -106,7 +106,7 @@ export class ViteNodeServer { } async resolveId(id: string, importer?: string, transformMode?: 'web' | 'ssr'): Promise { - if (importer && !importer.startsWith(this.server.config.root)) + if (importer && !importer.startsWith(withTrailingSlash(this.server.config.root))) importer = resolve(this.server.config.root, importer) const mode = transformMode ?? ((importer && this.getTransformMode(importer)) || 'ssr') return this.server.pluginContainer.resolveId(id, importer, { ssr: mode === 'ssr' }) @@ -182,7 +182,7 @@ export class ViteNodeServer { const cacheDir = this.options.deps?.cacheDir if (cacheDir && id.includes(cacheDir)) { - if (!id.startsWith(this.server.config.root)) + if (!id.startsWith(withTrailingSlash(this.server.config.root))) id = join(this.server.config.root, id) const timeout = setTimeout(() => { throw new Error(`ViteNodeServer: ${id} not found. This is a bug, please report it.`) diff --git a/packages/vite-node/src/source-map.ts b/packages/vite-node/src/source-map.ts index e9d67c71bd05..de9aa165de35 100644 --- a/packages/vite-node/src/source-map.ts +++ b/packages/vite-node/src/source-map.ts @@ -1,6 +1,7 @@ import type { TransformResult } from 'vite' import { dirname, isAbsolute, relative, resolve } from 'pathe' import type { EncodedSourceMap } from '@jridgewell/trace-mapping' +import { withTrailingSlash } from './utils' import { install } from './source-map-handler' interface InstallSourceMapSupportOptions { @@ -32,7 +33,7 @@ export function withInlineSourcemap(result: TransformResult, options: { // this is a bug in Vite // all files should be either absolute to the file system or relative to the source map file if (isAbsolute(source)) { - const actualPath = (!source.startsWith(options.root) && source.startsWith('/')) + const actualPath = (!source.startsWith(withTrailingSlash(options.root)) && source.startsWith('/')) ? resolve(options.root, source.slice(1)) : source return relative(dirname(options.filepath), actualPath) diff --git a/packages/vite-node/src/utils.ts b/packages/vite-node/src/utils.ts index f781e2984ef5..e6cdcaf7479d 100644 --- a/packages/vite-node/src/utils.ts +++ b/packages/vite-node/src/utils.ts @@ -22,7 +22,7 @@ export function slash(str: string) { export const VALID_ID_PREFIX = '/@id/' export function normalizeRequestId(id: string, base?: string): string { - if (base && id.startsWith(base)) + if (base && id.startsWith(withTrailingSlash(base))) id = `/${id.slice(base.length)}` // keep drive the same as in process cwd @@ -105,12 +105,12 @@ export function toFilePath(id: string, root: string): { path: string; exists: bo if (id.startsWith('/@fs/')) return { absolute: id.slice(4), exists: true } // check if /src/module.js -> /src/module.js - if (!id.startsWith(root) && id.startsWith('/')) { + if (!id.startsWith(withTrailingSlash(root)) && id.startsWith('/')) { const resolved = resolve(root, id.slice(1)) if (existsSync(cleanUrl(resolved))) return { absolute: resolved, exists: true } } - else if (id.startsWith(root) && existsSync(cleanUrl(id))) { + else if (id.startsWith(withTrailingSlash(root)) && existsSync(cleanUrl(id))) { return { absolute: id, exists: true } } return { absolute: id, exists: false } @@ -200,6 +200,13 @@ function traverseBetweenDirs( } } +export function withTrailingSlash(path: string): string { + if (path[path.length - 1] !== '/') + return `${path}/` + + return path +} + export function createImportMetaEnvProxy() { // packages/vitest/src/node/plugins/index.ts:146 const booleanKeys = [