Skip to content

Commit 1ce4db6

Browse files
filipesilvaclydin
authored andcommitted
fix(@ngtools/webpack): kill type checker on watch close
The forked type checker was not being disposed of when watch mode was being closed without the process exiting.
1 parent 7b8faae commit 1ce4db6

File tree

1 file changed

+27
-24
lines changed

1 file changed

+27
-24
lines changed

Diff for: packages/@ngtools/webpack/src/angular_compiler_plugin.ts

+27-24
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ export class AngularCompilerPlugin implements Tapable {
115115
// TypeChecker process.
116116
private _forkTypeChecker = true;
117117
private _typeCheckerProcess: ChildProcess;
118+
private _forkedTypeCheckerInitialized = false;
118119

119120
private get _ngCompilerSupportsNewApi() {
120121
if (this._JitMode) {
@@ -323,7 +324,7 @@ export class AngularCompilerPlugin implements Tapable {
323324

324325
// Update the forked type checker with all changed compilation files.
325326
// This includes templates, that also need to be reloaded on the type checker.
326-
if (this._forkTypeChecker && !this._firstRun) {
327+
if (this._forkTypeChecker && this._typeCheckerProcess && !this._firstRun) {
327328
this._updateForkedTypeChecker(this._rootNames, this._getChangedCompilationFiles());
328329
}
329330

@@ -500,44 +501,42 @@ export class AngularCompilerPlugin implements Tapable {
500501
path.resolve(__dirname, typeCheckerFile),
501502
forkArgs,
502503
forkOptions);
503-
this._typeCheckerProcess.send(new InitMessage(this._compilerOptions, this._basePath,
504-
this._JitMode, this._rootNames));
505-
506-
// Cleanup.
507-
const killTypeCheckerProcess = () => {
508-
if (this._typeCheckerProcess && this._typeCheckerProcess.pid) {
509-
treeKill(this._typeCheckerProcess.pid, 'SIGTERM');
510-
this._typeCheckerProcess = undefined;
511-
this._forkTypeChecker = false;
512-
}
513-
};
514504

515505
// Handle child process exit.
516506
const handleChildProcessExit = () => {
517-
killTypeCheckerProcess();
507+
this._killForkedTypeChecker();
518508
const msg = 'AngularCompilerPlugin: Forked Type Checker exited unexpectedly. ' +
519-
'Falling back to typechecking on main thread.';
509+
'Falling back to type checking on main thread.';
520510
this._warnings.push(msg);
521511
};
522512
this._typeCheckerProcess.once('exit', handleChildProcessExit);
523513
this._typeCheckerProcess.once('SIGINT', handleChildProcessExit);
524514
this._typeCheckerProcess.once('uncaughtException', handleChildProcessExit);
525515

526516
// Handle parent process exit.
527-
const handleParentProcessExit = () => {
528-
killTypeCheckerProcess();
529-
process.exit();
530-
};
517+
const handleParentProcessExit = () => this._killForkedTypeChecker();
531518
process.once('exit', handleParentProcessExit);
532519
process.once('SIGINT', handleParentProcessExit);
533520
process.once('uncaughtException', handleParentProcessExit);
534521
}
535522

523+
private _killForkedTypeChecker() {
524+
if (this._typeCheckerProcess && this._typeCheckerProcess.pid) {
525+
treeKill(this._typeCheckerProcess.pid, 'SIGTERM');
526+
this._typeCheckerProcess = undefined;
527+
this._forkTypeChecker = false;
528+
}
529+
}
530+
536531
private _updateForkedTypeChecker(rootNames: string[], changedCompilationFiles: string[]) {
532+
if (!this._forkedTypeCheckerInitialized) {
533+
this._typeCheckerProcess.send(new InitMessage(this._compilerOptions, this._basePath,
534+
this._JitMode, this._rootNames));
535+
this._forkedTypeCheckerInitialized = true;
536+
}
537537
this._typeCheckerProcess.send(new UpdateMessage(rootNames, changedCompilationFiles));
538538
}
539539

540-
541540
// Registration hook for webpack plugin.
542541
apply(compiler: any) {
543542
// Decorate inputFileSystem to serve contents of CompilerHost.
@@ -608,6 +607,15 @@ export class AngularCompilerPlugin implements Tapable {
608607
});
609608
});
610609

610+
// Create and destroy forked type checker on watch mode.
611+
compiler.plugin('watch-run', (_compiler: any, callback: any) => {
612+
if (this._forkTypeChecker && !this._typeCheckerProcess) {
613+
this._createForkedTypeChecker();
614+
}
615+
callback();
616+
});
617+
compiler.plugin('watch-close', () => this._killForkedTypeChecker());
618+
611619
// Remake the plugin on each compilation.
612620
compiler.plugin('make', (compilation: any, cb: any) => this._make(compilation, cb));
613621
compiler.plugin('invalid', () => this._firstRun = false);
@@ -663,11 +671,6 @@ export class AngularCompilerPlugin implements Tapable {
663671
// Update the resource loader with the new webpack compilation.
664672
this._resourceLoader.update(compilation);
665673

666-
// Create a new process for the type checker on the second build if there isn't one yet.
667-
if (this._forkTypeChecker && !this._firstRun && !this._typeCheckerProcess) {
668-
this._createForkedTypeChecker();
669-
}
670-
671674
this._donePromise = Promise.resolve()
672675
.then(() => this._update())
673676
.then(() => {

0 commit comments

Comments
 (0)