Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ lib
dist
temp
target
pnpm-lock.yaml
pnpm-lock.yaml
# Line positions are significant for the sourcemap integration test
packages/integrate/__tests__/sourcemaps/throw-with-interfaces.ts

This file was deleted.

Binary file not shown.
52 changes: 24 additions & 28 deletions packages/integrate/__tests__/sourcemaps/sourcemaps.spec.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,32 @@
import { readFileSync } from 'fs'
import { join } from 'path'

import test from 'ava'

// @ts-expect-error
interface _Unused1 {}
// @ts-expect-error
interface _Unused2 {}
// @ts-expect-error
interface _Unused3 {}
// @ts-expect-error
interface _Unused4 {}
// @ts-expect-error
interface _Unused5 {}
// @ts-expect-error
interface _Unused6 {}
// @ts-expect-error
interface _Unused7 {}
// @ts-expect-error
interface _Unused8 {}
// @ts-expect-error
interface _Unused9 {}

test('should work with sourcemaps', (t) => {
test('should report correct line numbers in stack traces when sourceMap is true', (t) => {
if (process.platform === 'win32') {
return t.pass('Skip on Windows')
}
const projectRoot = join(__dirname, '..', '..', '..', '..')
t.snapshot(
new Error().stack
?.split('\n')
.map((l) => l.replace(projectRoot, ''))
.filter((n) => !n.includes('node:internal'))
.join('\n'),
)

// Read the helper file to find the actual line number of the throw statement.
// This makes the test resilient to reformatting: if the file layout changes,
// the expected line number updates automatically.
const helperPath = join(__dirname, 'throw-with-interfaces.ts')
const source = readFileSync(helperPath, 'utf-8')
const expectedLine = source.split('\n').findIndex((line) => line.includes("throw new Error('sourcemap-test')")) + 1
t.true(expectedLine > 0, 'Could not find throw statement in throw-with-interfaces.ts')

// The helper file has 9 TypeScript interfaces before the throw.
// SWC strips them during transpilation, so if source maps are broken
// the reported line number will be lower than the actual source line.
try {
require('./throw-with-interfaces').throwError()
t.fail('Expected throwError() to throw')
} catch (err) {
const stack = (err as Error).stack ?? ''
const match = stack.match(/throw-with-interfaces\.ts:(\d+)/)
t.truthy(match, `Stack trace should reference throw-with-interfaces.ts, got:\n${stack}`)
const actualLine = parseInt(match![1], 10)
t.is(actualLine, expectedLine, `Expected error on line ${expectedLine} but stack trace reported line ${actualLine}`)
}
})
17 changes: 17 additions & 0 deletions packages/integrate/__tests__/sourcemaps/throw-with-interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// @ts-nocheck — unused interfaces are intentional
// These type-only constructs are stripped by SWC during transpilation.
// If source maps are broken, the reported line numbers in stack traces
// will be offset by the number of stripped lines.
interface Unused1 { a: string }
interface Unused2 { b: number }
interface Unused3 { c: boolean }
interface Unused4 { d: string }
interface Unused5 { e: number }
interface Unused6 { f: boolean }
interface Unused7 { g: string }
interface Unused8 { h: number }
interface Unused9 { i: boolean }

exports.throwError = function throwError() {
throw new Error('sourcemap-test')
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ test('should force the jsx config', (t) => {
t.like(swcConfig, expected)
})

test('should set sourcemap to true when sourceMap is true and inlineSourceMap is not set', (t) => {
const options: ts.CompilerOptions = {
sourceMap: true,
}
const filename = 'some-file.ts'
const swcConfig = tsCompilerOptionsToSwcConfig(options, filename)
t.like(swcConfig, { sourcemap: true })
})

test('should set all values', (t) => {
const options: ts.CompilerOptions = {
module: ts.ModuleKind.CommonJS,
Expand Down
3 changes: 1 addition & 2 deletions packages/register/read-default-tsconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,7 @@ export function tsCompilerOptionsToSwcConfig(options: ts.CompilerOptions, filena
module: toModule(options.module ?? ts.ModuleKind.ES2015),
target: toTsTarget(target),
jsx: isJsx,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
sourcemap: options.sourceMap || enableInlineSourceMap ? 'inline' : Boolean(options.sourceMap),
sourcemap: enableInlineSourceMap ? 'inline' : Boolean(options.sourceMap),
experimentalDecorators: options.experimentalDecorators ?? false,
emitDecoratorMetadata: options.emitDecoratorMetadata ?? false,
useDefineForClassFields: getUseDefineForClassFields(options, target),
Expand Down