Home / File/ ssrStacktrace.ts — vite Source File

ssrStacktrace.ts — vite Source File

Architecture documentation for ssrStacktrace.ts, a typescript file in the vite codebase. 3 imports, 2 dependents.

File typescript ViteCore ConfigEngine 3 imports 2 dependents 4 functions

Entity Profile

Dependency Diagram

graph LR
  e29c58b0_0755_ae27_7a1e_c5e90513f90f["ssrStacktrace.ts"]
  51e96894_3556_ed5c_1ede_97d449867adf["node:path"]
  e29c58b0_0755_ae27_7a1e_c5e90513f90f --> 51e96894_3556_ed5c_1ede_97d449867adf
  b84d7b55_2c14_7c59_01d9_b663416bfad1["trace-mapping"]
  e29c58b0_0755_ae27_7a1e_c5e90513f90f --> b84d7b55_2c14_7c59_01d9_b663416bfad1
  2616bf8c_8895_7af5_fb6e_8424b9e71ea7[".."]
  e29c58b0_0755_ae27_7a1e_c5e90513f90f --> 2616bf8c_8895_7af5_fb6e_8424b9e71ea7
  a423a1ed_f7d8_0eb5_9b8f_ddfa7fa8147e["index.ts"]
  a423a1ed_f7d8_0eb5_9b8f_ddfa7fa8147e --> e29c58b0_0755_ae27_7a1e_c5e90513f90f
  b7a0ff91_0490_7aed_6486_84da56e8e026["ssrModuleLoader.ts"]
  b7a0ff91_0490_7aed_6486_84da56e8e026 --> e29c58b0_0755_ae27_7a1e_c5e90513f90f
  style e29c58b0_0755_ae27_7a1e_c5e90513f90f fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

import path from 'node:path'
import { TraceMap, originalPositionFor } from '@jridgewell/trace-mapping'
import type { EnvironmentModuleGraph } from '..'

let offset: number

function calculateOffsetOnce() {
  if (offset !== undefined) {
    return
  }

  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: EnvironmentModuleGraph,
): { result: string; alreadyRewritten: boolean } {
  calculateOffsetOnce()

  let alreadyRewritten = false
  const rewritten = stack
    .split('\n')
    .map((line) => {
      return line.replace(
        /^ {4}at (?:(\S.*?)\s\()?(.+?):(\d+)(?::(\d+))?\)?/,
        (input, varName, id, originalLine, originalColumn) => {
          if (!id) return input

          const mod = moduleGraph.getModuleById(id)
          const rawSourceMap = mod?.transformResult?.map

          if (!rawSourceMap) {
            return input
          }

          const traced = new TraceMap(rawSourceMap as any)
          const line = Number(originalLine) - offset
          // stacktrace's column is 1-indexed, but sourcemap's one is 0-indexed
          const column = Number(originalColumn) - 1
          if (line <= 0 || column < 0) {
            alreadyRewritten = true
            return input
          }

          const pos = originalPositionFor(traced, { line, column })
          if (!pos.source) {
            return input
          }

          const trimmedVarName = varName?.trim()
          const sourceFile = path.resolve(path.dirname(id), pos.source)
          // stacktrace's column is 1-indexed, but sourcemap's one is 0-indexed
          const source = `${sourceFile}:${pos.line}:${pos.column + 1}`
          if (!trimmedVarName || trimmedVarName === 'eval') {
            return `    at ${source}`
          } else {
            return `    at ${trimmedVarName} (${source})`
          }
        },
      )
    })
    .join('\n')
  return { result: rewritten, alreadyRewritten }
}

export function rebindErrorStacktrace(e: Error, stacktrace: string): void {
  const { configurable, writable } = Object.getOwnPropertyDescriptor(
    e,
    'stack',
  )!
  if (configurable) {
    Object.defineProperty(e, 'stack', {
      value: stacktrace,
      enumerable: true,
      configurable: true,
      writable: true,
    })
  } else if (writable) {
    e.stack = stacktrace
  }
}

const rewroteStacktraces = new WeakSet()

export function ssrFixStacktrace(
  e: Error,
  moduleGraph: EnvironmentModuleGraph,
): void {
  if (!e.stack) return
  // stacktrace shouldn't be rewritten more than once
  if (rewroteStacktraces.has(e)) return

  const { result: stacktrace, alreadyRewritten } = ssrRewriteStacktrace(
    e.stack,
    moduleGraph,
  )
  rebindErrorStacktrace(e, stacktrace)
  if (alreadyRewritten) {
    e.message +=
      ' (The stacktrace appears to be already rewritten by something else, but was passed to vite.ssrFixStacktrace. This may cause incorrect stacktraces.)'
  }

  rewroteStacktraces.add(e)
}

Domain

Subdomains

Dependencies

  • ..
  • node:path
  • trace-mapping

Frequently Asked Questions

What does ssrStacktrace.ts do?
ssrStacktrace.ts is a source file in the vite codebase, written in typescript. It belongs to the ViteCore domain, ConfigEngine subdomain.
What functions are defined in ssrStacktrace.ts?
ssrStacktrace.ts defines 4 function(s): calculateOffsetOnce, rebindErrorStacktrace, ssrFixStacktrace, ssrRewriteStacktrace.
What does ssrStacktrace.ts depend on?
ssrStacktrace.ts imports 3 module(s): .., node:path, trace-mapping.
What files import ssrStacktrace.ts?
ssrStacktrace.ts is imported by 2 file(s): index.ts, ssrModuleLoader.ts.
Where is ssrStacktrace.ts in the architecture?
ssrStacktrace.ts is located at packages/vite/src/node/ssr/ssrStacktrace.ts (domain: ViteCore, subdomain: ConfigEngine, directory: packages/vite/src/node/ssr).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free