Skip to content

Commit 1cac86b

Browse files
authored
Combine source map with source file output (#368)
1 parent 61f1c16 commit 1cac86b

File tree

4 files changed

+41
-55
lines changed

4 files changed

+41
-55
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"rimraf": "^2.5.4",
5959
"semver": "^5.1.0",
6060
"tslint": "^5.0.0",
61-
"tslint-config-standard": "^6.0.0",
61+
"tslint-config-standard": "^6.0.1",
6262
"typescript": "^2.1.4",
6363
"typings": "^2.0.0"
6464
},

src/_bin.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,6 @@ const argv = minimist<Argv>(process.argv.slice(2, stop), {
105105
}
106106
})
107107

108-
if (argv.version) {
109-
console.log(`ts-node v${VERSION}`)
110-
console.log(`node ${process.version}`)
111-
process.exit(0)
112-
}
113-
114108
if (argv.help) {
115109
console.log(`
116110
Usage: ts-node [options] [ -e script | script.ts ] [arguments]
@@ -155,8 +149,17 @@ const service = register({
155149
fileExists: isEval ? fileExistsEval : fileExists
156150
})
157151

152+
// Output project information.
153+
if (argv.version) {
154+
console.log(`ts-node v${VERSION}`)
155+
console.log(`node ${process.version}`)
156+
console.log(`typescript v${service.ts.version}`)
157+
console.log(`cache ${JSON.stringify(service.cachedir)}`)
158+
process.exit(0)
159+
}
160+
158161
// Require specified modules before start-up.
159-
;(Module as any)._preloadModules(arrify(argv.require))
162+
(Module as any)._preloadModules(arrify(argv.require))
160163

161164
/**
162165
* Eval helpers.

src/index.spec.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,6 @@ describe('ts-node', function () {
252252
require('../tests/with-jsx.tsx')
253253
} catch (error) {
254254
expect(error.stack).to.contain('SyntaxError: Unexpected token <\n')
255-
expect(compiled).to.not.contain('//# sourceMappingURL=w') // First letter of filename.
256-
expect(compiled).to.match(/\/\/# sourceMappingURL=.*\.jsx.map$/)
257255
done()
258256
}
259257
})

src/index.ts

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export interface Options {
6363
interface Cache {
6464
contents: { [fileName: string]: string }
6565
versions: { [fileName: string]: number }
66-
sourceMaps: { [fileName: string]: string }
66+
outputs: { [fileName: string]: string }
6767
}
6868

6969
/**
@@ -115,6 +115,8 @@ export function normalizeSlashes (value: string): string {
115115
export interface Register {
116116
cwd: string
117117
extensions: string[]
118+
cachedir: string
119+
ts: TSCommon
118120
compile (code: string, fileName: string, lineOffset?: number): string
119121
getTypeInfo (code: string, fileName: string, position: number): TypeInfo
120122
}
@@ -150,7 +152,7 @@ export function register (options: Options = {}): Register {
150152
const cache: Cache = {
151153
contents: Object.create(null),
152154
versions: Object.create(null),
153-
sourceMaps: Object.create(null)
155+
outputs: Object.create(null)
154156
}
155157

156158
const ignore = arrify(
@@ -165,13 +167,8 @@ export function register (options: Options = {}): Register {
165167
// Install source map support and read from cache.
166168
sourceMapSupport.install({
167169
environment: 'node',
168-
retrieveSourceMap (fileName: string) {
169-
if (cache.sourceMaps[fileName]) {
170-
return {
171-
url: cache.sourceMaps[fileName],
172-
map: getFile(cache.sourceMaps[fileName])
173-
}
174-
}
170+
retrieveFile (path: string) {
171+
return cache.outputs[path]
175172
}
176173
})
177174

@@ -187,9 +184,6 @@ export function register (options: Options = {}): Register {
187184
getCompilerDigest({ version: ts.version, fast, ignoreWarnings, disableWarnings, config, compiler })
188185
)
189186

190-
// Make sure the cache directory _always_ exists (source maps write there).
191-
mkdirp.sync(cachedir)
192-
193187
// Render the configuration errors and exit the script.
194188
if (configDiagnostics.length) {
195189
throw new TSError(formatDiagnostics(configDiagnostics, cwd, ts, 0))
@@ -243,7 +237,6 @@ export function register (options: Options = {}): Register {
243237
cachedir,
244238
shouldCache,
245239
getFile,
246-
fileExists,
247240
cache,
248241
getOutput,
249242
getExtension
@@ -325,7 +318,6 @@ export function register (options: Options = {}): Register {
325318
cachedir,
326319
shouldCache,
327320
getFile,
328-
fileExists,
329321
cache,
330322
function (code: string, fileName: string, lineOffset?: number) {
331323
setCache(code, fileName)
@@ -346,10 +338,12 @@ export function register (options: Options = {}): Register {
346338
}
347339
}
348340

349-
const register: Register = { cwd, compile, getTypeInfo, extensions }
341+
const register: Register = { cwd, compile, getTypeInfo, extensions, cachedir, ts }
350342

351343
// Register the extensions.
352-
extensions.forEach(extension => registerExtension(extension, ignore, register, originalJsHandler))
344+
extensions.forEach(extension => {
345+
registerExtension(extension, ignore, register, originalJsHandler)
346+
})
353347

354348
return register
355349
}
@@ -453,49 +447,40 @@ function readThrough (
453447
cachedir: string,
454448
shouldCache: boolean,
455449
getFile: (fileName: string) => string,
456-
fileExists: (fileName: string) => boolean,
457450
cache: Cache,
458451
compile: (code: string, fileName: string, lineOffset?: number) => SourceOutput,
459452
getExtension: (fileName: string) => string
460453
) {
461454
if (shouldCache === false) {
462455
return function (code: string, fileName: string, lineOffset?: number) {
463-
const cachePath = join(cachedir, getCacheName(code, fileName))
464-
const extension = getExtension(fileName)
465-
const sourceMapPath = `${cachePath}${extension}.map`
466-
const out = compile(code, fileName, lineOffset)
467-
468-
cache.sourceMaps[fileName] = sourceMapPath
469-
470-
const output = updateOutput(out[0], fileName, extension, sourceMapPath)
471-
const sourceMap = updateSourceMap(out[1], fileName)
456+
const [value, sourceMap] = compile(code, fileName, lineOffset)
457+
const output = updateOutput(value, fileName, sourceMap)
472458

473-
writeFileSync(sourceMapPath, sourceMap)
459+
cache.outputs[fileName] = output
474460

475461
return output
476462
}
477463
}
478464

465+
// Make sure the cache directory exists before continuing.
466+
mkdirp.sync(cachedir)
467+
479468
return function (code: string, fileName: string, lineOffset?: number) {
480469
const cachePath = join(cachedir, getCacheName(code, fileName))
481470
const extension = getExtension(fileName)
482471
const outputPath = `${cachePath}${extension}`
483-
const sourceMapPath = `${outputPath}.map`
484472

485-
cache.sourceMaps[fileName] = sourceMapPath
486-
487-
// Use the cache when available.
488-
if (fileExists(outputPath)) {
489-
return getFile(outputPath)
490-
}
491-
492-
const out = compile(code, fileName, lineOffset)
473+
try {
474+
const output = getFile(outputPath)
475+
cache.outputs[fileName] = output
476+
return output
477+
} catch (err) {/* Ignore. */}
493478

494-
const output = updateOutput(out[0], fileName, extension, sourceMapPath)
495-
const sourceMap = updateSourceMap(out[1], fileName)
479+
const [value, sourceMap] = compile(code, fileName, lineOffset)
480+
const output = updateOutput(value, fileName, sourceMap)
496481

482+
cache.outputs[fileName] = output
497483
writeFileSync(outputPath, output)
498-
writeFileSync(sourceMapPath, sourceMap)
499484

500485
return output
501486
}
@@ -504,11 +489,11 @@ function readThrough (
504489
/**
505490
* Update the output remapping the source map.
506491
*/
507-
function updateOutput (outputText: string, fileName: string, extension: string, sourceMapPath: string) {
508-
// Replace the original extension (E.g. `.ts`).
509-
const ext = extname(fileName)
510-
const originalPath = basename(fileName).slice(0, -ext.length) + `${extension}.map`
511-
return outputText.slice(0, -originalPath.length) + sourceMapPath.replace(/\\/g, '/')
492+
function updateOutput (outputText: string, fileName: string, sourceMap: string) {
493+
const base64Map = new Buffer(updateSourceMap(sourceMap, fileName), 'utf8').toString('base64')
494+
const sourceMapContent = `data:application/json;charset=utf-8;base64,${base64Map}`
495+
496+
return outputText.slice(0, -1 * (basename(fileName).length + 4)) + sourceMapContent
512497
}
513498

514499
/**
@@ -528,7 +513,7 @@ function updateSourceMap (sourceMapText: string, fileName: string) {
528513
function getCacheName (sourceCode: string, fileName: string) {
529514
return crypto.createHash('sha256')
530515
.update(extname(fileName), 'utf8')
531-
.update('\0', 'utf8')
516+
.update('\x001\x00', 'utf8') // Store "cache version" in hash.
532517
.update(sourceCode, 'utf8')
533518
.digest('hex')
534519
}

0 commit comments

Comments
 (0)