/
compile-source-files.ts
98 lines (83 loc) · 3.27 KB
/
compile-source-files.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
import * as ng from '@angular/compiler-cli';
import * as ts from 'typescript';
import * as log from '../utils/log';
import { cacheCompilerHost } from '../ts/cache-compiler-host';
import { StylesheetProcessor } from '../styles/stylesheet-processor';
import { BuildGraph } from '../graph/build-graph';
import { EntryPointNode, isEntryPointInProgress } from '../ng-package/nodes';
import { NgccProcessor } from './ngcc-processor';
import { ngccTransformCompilerHost } from '../ts/ngcc-transform-compiler-host';
import { createEmitCallback } from './create-emit-callback';
export async function compileSourceFiles(
graph: BuildGraph,
tsConfig: ng.ParsedConfiguration,
moduleResolutionCache: ts.ModuleResolutionCache,
stylesheetProcessor: StylesheetProcessor,
extraOptions?: Partial<ng.CompilerOptions>,
ngccProcessor?: NgccProcessor,
) {
log.debug(`ngc (v${ng.VERSION.full})`);
const tsConfigOptions: ng.CompilerOptions = { ...tsConfig.options, ...extraOptions };
const entryPoint = graph.find(isEntryPointInProgress()) as EntryPointNode;
let tsCompilerHost = cacheCompilerHost(
graph,
entryPoint,
tsConfigOptions,
moduleResolutionCache,
stylesheetProcessor,
);
if (tsConfigOptions.enableIvy && ngccProcessor) {
tsCompilerHost = ngccTransformCompilerHost(tsCompilerHost, tsConfigOptions, ngccProcessor, moduleResolutionCache);
}
// ng.CompilerHost
const ngCompilerHost = ng.createCompilerHost({
options: tsConfigOptions,
tsHost: tsCompilerHost,
});
const scriptTarget = tsConfigOptions.target;
const cache = entryPoint.cache;
const oldProgram = cache.oldPrograms && (cache.oldPrograms[scriptTarget] as ng.Program | undefined);
const ngProgram = ng.createProgram({
rootNames: tsConfig.rootNames,
options: tsConfigOptions,
host: ngCompilerHost,
oldProgram,
});
await ngProgram.loadNgStructureAsync();
log.debug(
`ngc program structure is reused: ${
oldProgram ? (oldProgram.getTsProgram() as any).structureIsReused : 'No old program'
}`,
);
cache.oldPrograms = { ...cache.oldPrograms, [scriptTarget]: ngProgram };
const allDiagnostics = [
...ngProgram.getTsOptionDiagnostics(),
...ngProgram.getNgOptionDiagnostics(),
...ngProgram.getTsSyntacticDiagnostics(),
...ngProgram.getTsSemanticDiagnostics(),
...ngProgram.getNgSemanticDiagnostics(),
...ngProgram.getNgStructuralDiagnostics(),
];
// if we have an error we don't want to transpile.
const hasError = ng.exitCodeFromResult(allDiagnostics) > 0;
if (!hasError) {
const emitFlags = tsConfigOptions.declaration ? tsConfig.emitFlags : ng.EmitFlags.JS;
// certain errors are only emitted by a compilation hence append to previous diagnostics
const { diagnostics } = ngProgram.emit({
emitFlags,
// For Ivy we don't need a custom emitCallback to have tsickle transforms
emitCallback: tsConfigOptions.enableIvy ? undefined : createEmitCallback(tsConfigOptions),
});
allDiagnostics.push(...diagnostics);
}
if (allDiagnostics.length === 0) {
return;
}
const exitCode = ng.exitCodeFromResult(allDiagnostics);
const formattedDiagnostics = ng.formatDiagnostics(allDiagnostics);
if (exitCode !== 0) {
throw new Error(formattedDiagnostics);
} else {
log.msg(formattedDiagnostics);
}
}