diff --git a/packages/vite/src/node/ssr/ssrStacktrace.ts b/packages/vite/src/node/ssr/ssrStacktrace.ts index c4b59fbf086da1..d15c4d94ae0de3 100644 --- a/packages/vite/src/node/ssr/ssrStacktrace.ts +++ b/packages/vite/src/node/ssr/ssrStacktrace.ts @@ -1,6 +1,17 @@ import { SourceMapConsumer, RawSourceMap } from 'source-map' import { ModuleGraph } from '../server/moduleGraph' +let offset: number +try { + new Function('throw new Error(1)')() +} catch (e) { + // in Node 12, stack traces account for the function wrapper. + // in Node 13 and later, the function wrapper adds two lines, + // which must be subtracted to generate a valid mapping + const match = /:(\d+):\d+\)$/.exec(e.stack.split('\n')[1]) + offset = match ? +match[1] - 1 : 0 +} + export function ssrRewriteStacktrace(stack: string, moduleGraph: ModuleGraph) { return stack .split('\n') @@ -22,9 +33,7 @@ export function ssrRewriteStacktrace(stack: string, moduleGraph: ModuleGraph) { ) const pos = consumer.originalPositionFor({ - // source map lines generated via new Function() in Node.js is always - // incremented by 2 due to the function wrapper - line: Number(line) - 2, + line: Number(line) - offset, column: Number(column), bias: SourceMapConsumer.LEAST_UPPER_BOUND })