Skip to content

Commit 54d1bfa

Browse files
authored
Fix #1060 (#1087)
* Fix #1060 * fix linter failures * fix lint failure * fix test coverage * fix tests on windows * generous timeout for npm install before() hook hopefully to avoid CI timeouts
1 parent 04e7896 commit 54d1bfa

File tree

3 files changed

+132
-4
lines changed

3 files changed

+132
-4
lines changed

src/index.spec.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { unlinkSync, existsSync, lstatSync } from 'fs'
99
import * as promisify from 'util.promisify'
1010
import { sync as rimrafSync } from 'rimraf'
1111
import { createRequire, createRequireFromPath } from 'module'
12+
import { pathToFileURL } from 'url'
1213
import Module = require('module')
1314

1415
const execP = promisify(exec)
@@ -28,7 +29,7 @@ let { register, create, VERSION }: typeof tsNodeTypes = {} as any
2829

2930
// Pack and install ts-node locally, necessary to test package "exports"
3031
before(async function () {
31-
this.timeout(30000)
32+
this.timeout(5 * 60e3)
3233
rimrafSync(join(TEST_DIR, 'node_modules'))
3334
await execP(`npm install`, { cwd: TEST_DIR })
3435
const packageLockPath = join(TEST_DIR, 'package-lock.json')
@@ -729,7 +730,7 @@ describe('ts-node', function () {
729730
describe('esm', () => {
730731
this.slow(1000)
731732

732-
const cmd = `node --loader ts-node/esm.mjs`
733+
const cmd = `node --loader ts-node/esm`
733734

734735
if (semver.gte(process.version, '13.0.0')) {
735736
it('should compile and execute as ESM', (done) => {
@@ -740,6 +741,19 @@ describe('ts-node', function () {
740741
return done()
741742
})
742743
})
744+
it('should use source maps', function (done) {
745+
exec(`${cmd} throw.ts`, { cwd: join(__dirname, '../tests/esm') }, function (err, stdout) {
746+
expect(err).not.to.equal(null)
747+
expect(err!.message).to.contain([
748+
`${pathToFileURL(join(__dirname, '../tests/esm/throw.ts'))}:100`,
749+
' bar () { throw new Error(\'this is a demo\') }',
750+
' ^',
751+
'Error: this is a demo'
752+
].join('\n'))
753+
754+
return done()
755+
})
756+
})
743757
it('supports --experimental-specifier-resolution=node', (done) => {
744758
exec(`${cmd} --experimental-specifier-resolution=node index.ts`, { cwd: join(__dirname, '../tests/esm-node-resolver') }, function (err, stdout) {
745759
expect(err).to.equal(null)

src/index.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import sourceMapSupport = require('source-map-support')
33
import * as ynModule from 'yn'
44
import { BaseError } from 'make-error'
55
import * as util from 'util'
6+
import { fileURLToPath } from 'url'
67
import * as _ts from 'typescript'
78

89
/**
@@ -445,8 +446,18 @@ export function create (rawOptions: CreateOptions = {}): Register {
445446
// Install source map support and read from memory cache.
446447
sourceMapSupport.install({
447448
environment: 'node',
448-
retrieveFile (path: string) {
449-
return outputCache.get(normalizeSlashes(path))?.content || ''
449+
retrieveFile (pathOrUrl: string) {
450+
let path = pathOrUrl
451+
// If it's a file URL, convert to local path
452+
// Note: fileURLToPath does not exist on early node v10
453+
// I could not find a way to handle non-URLs except to swallow an error
454+
if (options.experimentalEsmLoader && path.startsWith('file://')) {
455+
try {
456+
path = fileURLToPath(path)
457+
} catch (e) {/* swallow error */}
458+
}
459+
path = normalizeSlashes(path)
460+
return outputCache.get(path)?.content || ''
450461
}
451462
})
452463

tests/esm/throw.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// intentional whitespace to prove that sourcemaps are working. Throw should happen on line 100.
2+
// 100 lines is meant to be far more space than the helper functions would take.
3+
class Foo {
4+
5+
6+
7+
8+
9+
10+
11+
12+
13+
14+
15+
16+
17+
18+
19+
20+
21+
22+
23+
24+
25+
26+
27+
28+
29+
30+
31+
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
42+
43+
44+
45+
46+
47+
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+
69+
70+
71+
72+
73+
74+
75+
76+
77+
78+
79+
80+
81+
82+
83+
84+
85+
86+
87+
88+
89+
90+
91+
92+
93+
94+
95+
96+
97+
98+
99+
constructor () { this.bar() }
100+
bar () { throw new Error('this is a demo') }
101+
}
102+
new Foo()
103+
export {}

0 commit comments

Comments
 (0)