/
run-program.ts
100 lines (85 loc) · 3.99 KB
/
run-program.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 type * as d from '../../declarations';
import { basename, join } from 'path';
import { convertDecoratorsToStatic } from '../transformers/decorators-to-static/convert-decorators';
import { generateAppTypes } from '../types/generate-app-types';
import { getComponentsFromModules, isOutputTargetDistTypes } from '../output-targets/output-utils';
import { loadTypeScriptDiagnostics, normalizePath } from '@utils';
import { resolveComponentDependencies } from '../entries/resolve-component-dependencies';
import type ts from 'typescript';
import { updateComponentBuildConditionals } from '../app-core/app-data';
import { updateModule } from '../transformers/static-to-meta/parse-static';
import { updateStencilTypesImports } from '../types/stencil-types';
import { validateTranspiledComponents } from './validate-components';
export const runTsProgram = async (config: d.Config, compilerCtx: d.CompilerCtx, buildCtx: d.BuildCtx, tsBuilder: ts.BuilderProgram) => {
const tsSyntactic = loadTypeScriptDiagnostics(tsBuilder.getSyntacticDiagnostics());
const tsGlobal = loadTypeScriptDiagnostics(tsBuilder.getGlobalDiagnostics());
const tsOptions = loadTypeScriptDiagnostics(tsBuilder.getOptionsDiagnostics());
buildCtx.diagnostics.push(...tsSyntactic);
buildCtx.diagnostics.push(...tsGlobal);
buildCtx.diagnostics.push(...tsOptions);
if (buildCtx.hasError) {
return false;
}
const tsProgram = tsBuilder.getProgram();
const tsTypeChecker = tsProgram.getTypeChecker();
const typesOutputTarget = config.outputTargets.filter(isOutputTargetDistTypes);
const emitCallback: ts.WriteFileCallback = (emitFilePath, data, _w, _e, tsSourceFiles) => {
if (emitFilePath.endsWith('.js')) {
updateModule(config, compilerCtx, buildCtx, tsSourceFiles[0], data, emitFilePath, tsTypeChecker, null);
} else if (emitFilePath.endsWith('.d.ts')) {
const relativeEmitFilepath = getRelativeDts(config, tsSourceFiles[0].fileName, emitFilePath);
typesOutputTarget.forEach(o => {
const distPath = join(o.typesDir, relativeEmitFilepath);
data = updateStencilTypesImports(o.typesDir, distPath, data);
compilerCtx.fs.writeFile(distPath, data);
});
}
};
// Emit files that changed
tsBuilder.emit(undefined, emitCallback, undefined, false, {
before: [convertDecoratorsToStatic(config, buildCtx.diagnostics, tsTypeChecker)],
});
const changedmodules = Array.from(compilerCtx.changedModules.keys());
buildCtx.debug('Transpiled modules: ' + JSON.stringify(changedmodules, null, '\n'));
// Finalize components metadata
buildCtx.moduleFiles = Array.from(compilerCtx.moduleMap.values());
buildCtx.components = getComponentsFromModules(buildCtx.moduleFiles);
updateComponentBuildConditionals(compilerCtx.moduleMap, buildCtx.components);
resolveComponentDependencies(buildCtx.components);
validateTranspiledComponents(config, buildCtx);
if (buildCtx.hasError) {
return false;
}
// create the components.d.ts file and write to disk
const hasTypesChanged = await generateAppTypes(config, compilerCtx, buildCtx, 'src');
if (hasTypesChanged) {
return true;
}
if (config.validateTypes) {
const tsSemantic = loadTypeScriptDiagnostics(tsBuilder.getSemanticDiagnostics());
if (config.devMode) {
tsSemantic.forEach(semanticDiagnostic => {
// Unused variable errors become warnings in dev mode
if (semanticDiagnostic.code === '6133' || semanticDiagnostic.code === '6192') {
semanticDiagnostic.level = 'warn';
}
});
}
buildCtx.diagnostics.push(...tsSemantic);
}
return false;
};
const getRelativeDts = (config: d.Config, srcPath: string, emitDtsPath: string) => {
const parts: string[] = [];
srcPath = normalizePath(srcPath);
for (let i = 0; i < 30; i++) {
if (config.srcDir === srcPath) {
break;
}
const b = basename(emitDtsPath);
parts.push(b);
emitDtsPath = join(emitDtsPath, '..');
srcPath = normalizePath(join(srcPath, '..'));
}
return join.apply(null, parts.reverse());
};