/
build-utils.ts
139 lines (110 loc) · 4.09 KB
/
build-utils.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { BuildCtx, CompilerCtx, Config, WatcherResults } from '../../declarations';
import { catchError, hasError } from '../util';
import { generateBuildResults, generateBuildStats } from './build-results';
import { initWatcher } from '../watcher/watcher-init';
export function getBuildContext(config: Config, compilerCtx: CompilerCtx, watcher: WatcherResults) {
// do a full build if there is no watcher
// or the watcher said the config has updated
// or we've never had a successful build yet
const requiresFullBuild = !watcher || watcher.configUpdated || !compilerCtx.hasSuccessfulBuild;
const isRebuild = !!watcher;
compilerCtx.isRebuild = isRebuild;
const msg = `${isRebuild ? 'rebuild' : 'build'}, ${config.fsNamespace}, ${config.devMode ? 'dev' : 'prod'} mode, started`;
// increment the active build id
compilerCtx.activeBuildId++;
// data for one build
const buildCtx: BuildCtx = {
requiresFullBuild: requiresFullBuild,
buildId: compilerCtx.activeBuildId,
componentRefs: [],
moduleGraph: [],
diagnostics: [],
entryPoints: [],
entryModules: [],
components: [],
transpileBuildCount: 0,
bundleBuildCount: 0,
appFileBuildCount: 0,
indexBuildCount: 0,
aborted: false,
startTime: Date.now(),
timeSpan: config.logger.createTimeSpan(msg),
hasChangedJsText: false,
filesWritten: [],
filesChanged: watcher ? watcher.filesChanged : [],
filesUpdated: watcher ? watcher.filesUpdated : [],
filesAdded: watcher ? watcher.filesAdded : [],
filesDeleted: watcher ? watcher.filesDeleted : [],
dirsDeleted: watcher ? watcher.dirsDeleted : [],
dirsAdded: watcher ? watcher.dirsAdded : []
};
buildCtx.shouldAbort = () => {
return shouldAbort(compilerCtx, buildCtx);
};
buildCtx.finish = async () => {
try {
// setup watcher if need be
initWatcher(config, compilerCtx);
} catch (e) {
catchError(buildCtx.diagnostics, e);
}
return finishBuild(config, compilerCtx, buildCtx);
};
return buildCtx;
}
async function finishBuild(config: Config, compilerCtx: CompilerCtx, buildCtx: BuildCtx) {
const buildResults = generateBuildResults(config, compilerCtx, buildCtx);
// log any errors/warnings
config.logger.printDiagnostics(buildResults.diagnostics);
// create a nice pretty message stating what happend
const buildText = compilerCtx.isRebuild ? 'rebuild' : 'build';
let watchText = config.watch ? ', watching for changes...' : '';
let buildStatus = 'finished';
let statusColor = 'green';
let bold = true;
if (buildResults.hasError) {
compilerCtx.lastBuildHadError = true;
buildStatus = 'failed';
statusColor = 'red';
} else if (buildResults.aborted) {
buildStatus = 'aborted';
watchText = '';
statusColor = 'dim';
bold = false;
} else {
compilerCtx.hasSuccessfulBuild = true;
compilerCtx.lastBuildHadError = false;
}
// print out the time it took to build
// and add the duration to the build results
buildCtx.timeSpan.finish(`${buildText} ${buildStatus}${watchText}`, statusColor, bold, true);
// write the build stats
await generateBuildStats(config, compilerCtx, buildCtx, buildResults);
// clear it all out for good measure
for (const k in buildCtx) {
(buildCtx as any)[k] = null;
}
// write all of our logs to disk if config'd to do so
config.logger.writeLogs(compilerCtx.isRebuild);
// emit a build event, which happens for inital build and rebuilds
compilerCtx.events.emit('build', buildResults);
if (compilerCtx.isRebuild) {
// emit a rebuild event, which happens only for rebuilds
compilerCtx.events.emit('rebuild', buildResults);
}
return buildResults;
}
function shouldAbort(ctx: CompilerCtx, buildCtx: BuildCtx) {
if (ctx.activeBuildId > buildCtx.buildId || buildCtx.aborted) {
buildCtx.aborted = true;
return true;
}
if (hasError(buildCtx.diagnostics)) {
// remember if the last build had an error or not
// this is useful if the next build should do a full build or not
ctx.lastBuildHadError = true;
buildCtx.aborted = true;
return true;
}
return false;
}