/
instance.ts
78 lines (66 loc) · 2.72 KB
/
instance.ts
1
2
3
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
import type { Logger } from 'bs-logger'
import type { ConfigSet } from '../config/config-set'
import type { CompileFn, CompilerInstance, TsCompiler } from '../types'
import { initializeLanguageServiceInstance } from './language-service'
import { initializeTranspilerInstance } from './transpiler'
import { stringify } from '../utils/json'
/**
* Rely on TypeScript compiled output generation which contains this prefix to point to sourcemap location.
*/
export const SOURCE_MAPPING_PREFIX = 'sourceMappingURL='
/**
* Update the output remapping the source map.
*/
export function updateOutput(outputText: string, normalizedFileName: string, sourceMap: string): string {
const base64Map = Buffer.from(updateSourceMap(sourceMap, normalizedFileName), 'utf8').toString('base64')
const sourceMapContent = `data:application/json;charset=utf-8;base64,${base64Map}`
// sourceMappingURL= prefix is always at the end of compiledOutput, using lastIndexOf should be the safest way to substring
return (
outputText.slice(0, outputText.lastIndexOf(SOURCE_MAPPING_PREFIX) + SOURCE_MAPPING_PREFIX.length) + sourceMapContent
)
}
/**
* Update the source map contents for improved output.
*/
const updateSourceMap = (sourceMapText: string, normalizedFileName: string): string => {
const sourceMap = JSON.parse(sourceMapText)
sourceMap.file = normalizedFileName
sourceMap.sources = [normalizedFileName]
delete sourceMap.sourceRoot
return stringify(sourceMap)
}
/**
* Compile files which are provided by jest via transform config and cache the result in file system if users run with
* cache mode
*/
const compileAndUpdateOutput = (compileFn: CompileFn, logger: Logger) => (
code: string,
fileName: string,
lineOffset?: number,
): string => {
logger.debug({ fileName }, 'compileAndUpdateOutput(): get compile output')
const [value, sourceMap] = compileFn(code, fileName, lineOffset)
return updateOutput(value, fileName, sourceMap)
}
/**
* Register TypeScript compiler instance.
*
* @internal
*/
export const createCompilerInstance = (configs: ConfigSet): TsCompiler => {
const logger = configs.logger.child({ namespace: 'ts-compiler' })
const {
parsedTsConfig: { options: compilerOptions },
} = configs
const extensions = ['.ts', '.tsx']
// Enable `allowJs` when flag is set.
if (compilerOptions.allowJs) {
extensions.push('.js')
extensions.push('.jsx')
}
const compilerInstance: CompilerInstance = !configs.isolatedModules
? initializeLanguageServiceInstance(configs, logger) // Use language services by default
: initializeTranspilerInstance(configs, logger)
const compile = compileAndUpdateOutput(compilerInstance.compileFn, logger)
return { cwd: configs.cwd, compile, program: compilerInstance.program }
}