-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathplugin.ts
100 lines (85 loc) · 2.98 KB
/
plugin.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* */
import ts from 'typescript'
import Logger from './logger'
import { convertErrors, outputErrors } from './format-errors'
import { CompilerHost } from './compiler-host'
import { resolveOptions } from './resolve-options'
import { transpile } from './transpiler'
import { isTypescript, isTypescriptDeclaration, isJson, stripDoubleExtension } from './utils'
const logger = new Logger({ debug: false })
const host = getHost()
/*
* persist CompilerHost instance between instantiations of the plugin and expose it to the world
*/
function getHost(): CompilerHost {
const __global: any = typeof (self) !== 'undefined' ? self : global
__global.tsHost = __global.tsHost || new CompilerHost()
return __global.tsHost
}
/*
* SystemJS translate hook
* load.name
* load.address
* load.metadata
* load.source: the fetched source
*/
export async function translate(load: Module): Promise<string> {
const loader = this
logger.debug(`systemjs translating ${load.address}`)
/* No need to translate tsconfig.json files */
if (isJson(load.address)) return load.source
/* resolve the typescript options for this file, this may involve loading tsconfig.json */
const options = await resolveOptions(
SystemJS.typescriptOptions,
load.metadata.typescriptOptions,
load.address,
_fetchJson)
/* create/update the source file in typescript */
host.addFile(load.address, load.source, options.target)
/* typescript declaration files have no executable source */
if (isTypescriptDeclaration(load.address)) {
load.source = ''
}
else {
/* transpile the source */
const result = transpile(load.address, options, host)
load.metadata.tserrors = convertErrors(result.diags)
outputErrors(load.metadata.tserrors, logger)
if (result.failure)
throw new Error('TypeScript transpilation failed')
load.source = result.js
if (isTypescript(load.address)) {
if (options.module === ts.ModuleKind.System)
load.metadata.format = 'register'
else if (options.module === ts.ModuleKind.ES2015)
load.metadata.format = 'esm'
else if (options.module === ts.ModuleKind.CommonJS)
load.metadata.format = 'cjs'
else if (options.module === ts.ModuleKind.AMD)
load.metadata.format = 'amd'
}
if (result.sourceMap)
load.metadata.sourceMap = JSON.parse(result.sourceMap)
}
return load.source
}
/*
* SystemJS instantiate hook
* load.name
* load.address
* load.metadata
* load.source: the fetched source
*/
export function instantiate(load: Module, origInstantiate: any) {
logger.debug(`systemjs instantiating ${load.address}`)
return isJson(load.address) ? JSON.parse(load.source) : origInstantiate(load)
}
/*
* called by resolveOptions when it needs to fetch tsconfig.json
*/
async function _fetchJson(fileName: string, parentAddress: string): Promise<string> {
const address = await SystemJS.normalize(fileName, parentAddress);
const json = await SystemJS.import(stripDoubleExtension(address) + '!' + __moduleName, parentAddress)
logger.debug(`fetched ${fileName}`)
return JSON.stringify(json)
}