in server/src/session.ts [1159:1221]
private async runNgcc(project: ts.server.Project): Promise<void> {
if (!isConfiguredProject(project)) {
return;
}
// Disable language service until ngcc is completed.
this.disableLanguageServiceForProject(project, 'ngcc is running');
const configFilePath = project.getConfigFilePath();
this.connection.sendProgress(NgccProgressType, NgccProgressToken, {
done: false,
configFilePath,
message: `Running ngcc for ${configFilePath}`,
});
let success = false;
try {
this.projectNgccQueue.push({project, done: false});
await resolveAndRunNgcc(configFilePath, {
report: (msg: string) => {
this.connection.sendProgress(NgccProgressType, NgccProgressToken, {
done: false,
configFilePath,
message: msg,
});
},
});
success = true;
} catch (e) {
this.error(
`Failed to run ngcc for ${
configFilePath}, language service may not operate correctly:\n` +
` ${e.message}`);
} finally {
const loadingStatus = this.projectNgccQueue.find(p => p.project === project);
if (loadingStatus !== undefined) {
loadingStatus.done = true;
}
this.connection.sendProgress(NgccProgressType, NgccProgressToken, {
done: true,
configFilePath,
success,
});
}
// ngcc processes might finish out of order, but we need to re-enable the language service for
// the projects in the same order that the ngcc processes were spawned in. With solution-style
// configs, we need to ensure that the language service enabling respects the order that the
// projects were defined in the references list. If we enable the language service out of order,
// the second project in the list will request diagnostics first and then be the project that's
// prioritized for that project's set of files. This will cause issues if the second project is,
// for example, one that only includes `*.spec.ts` files and not the entire set of files needed
// to compile the app (i.e. `*.module.ts`).
for (let i = 0; i < this.projectNgccQueue.length && this.projectNgccQueue[i].done; i++) {
// Re-enable language service even if ngcc fails, because users could fix
// the problem by running ngcc themselves. If we keep language service
// disabled, there's no way users could use the extension even after
// resolving ngcc issues. On the client side, we will warn users about
// potentially degraded experience.
this.enableLanguageServiceForProject(this.projectNgccQueue[i].project);
}
this.projectNgccQueue = this.projectNgccQueue.filter(({done}) => !done);
}