Skip to content

Commit 9b85c07

Browse files
nicojsclydin
authored andcommitted
fix(@ngtools/webpack): remove message handler on main process
Move the listening to messages from the type_checker.ts to a seperate type_checker_worker.ts file. Only start listening to messages when a magic 'auto start' argument is present in in the argument list, preventing undesired eaves dropping on other processes. Also rename type_checker.ts -> type_checker_messages.ts, as it now contains only the messages.
1 parent f830a8d commit 9b85c07

File tree

4 files changed

+73
-46
lines changed

4 files changed

+73
-46
lines changed

packages/@ngtools/webpack/src/angular_compiler_plugin.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
replaceResources,
2828
} from './transformers';
2929
import { time, timeEnd } from './benchmark';
30-
import { InitMessage, UpdateMessage } from './type_checker';
30+
import { InitMessage, UpdateMessage, AUTO_START_ARG } from './type_checker';
3131
import { gatherDiagnostics, hasErrors } from './gather_diagnostics';
3232
import {
3333
CompilerCliIsSupported,
@@ -466,7 +466,7 @@ export class AngularCompilerPlugin implements Tapable {
466466
const g: any = global;
467467
const typeCheckerFile: string = g['angularCliIsLocal']
468468
? './type_checker_bootstrap.js'
469-
: './type_checker.js';
469+
: './type_checker_worker.js';
470470

471471
const debugArgRegex = /--inspect(?:-brk|-port)?|--debug(?:-brk|-port)/;
472472

@@ -475,10 +475,15 @@ export class AngularCompilerPlugin implements Tapable {
475475
// Workaround for https://github.com/nodejs/node/issues/9435
476476
return !debugArgRegex.test(arg);
477477
});
478-
478+
// Signal the process to start listening for messages
479+
// Solves https://github.com/angular/angular-cli/issues/9071
480+
const forkArgs = [AUTO_START_ARG];
479481
const forkOptions: ForkOptions = { execArgv };
480482

481-
this._typeCheckerProcess = fork(path.resolve(__dirname, typeCheckerFile), [], forkOptions);
483+
this._typeCheckerProcess = fork(
484+
path.resolve(__dirname, typeCheckerFile),
485+
forkArgs,
486+
forkOptions);
482487
this._typeCheckerProcess.send(new InitMessage(this._compilerOptions, this._basePath,
483488
this._JitMode, this._rootNames));
484489

packages/@ngtools/webpack/src/type_checker.ts

+10-41
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
// @ignoreDep typescript
2-
import * as process from 'process';
32
import * as ts from 'typescript';
43
import chalk from 'chalk';
5-
6-
import { WebpackCompilerHost } from './compiler_host';
7-
import { time, timeEnd } from './benchmark';
8-
import { CancellationToken, gatherDiagnostics } from './gather_diagnostics';
94
import {
105
Program,
116
CompilerOptions,
@@ -14,12 +9,19 @@ import {
149
createCompilerHost,
1510
formatDiagnostics,
1611
} from './ngtools_api';
12+
import { WebpackCompilerHost } from './compiler_host';
13+
import { time, timeEnd } from './benchmark';
14+
import { CancellationToken, gatherDiagnostics } from './gather_diagnostics';
15+
16+
17+
// This file should run in a child process with the AUTO_START_ARG argument
1718

1819
// Force basic color support on terminals with no color support.
1920
// Chalk typings don't have the correct constructor parameters.
2021
const chalkCtx = new (chalk.constructor as any)(chalk.supportsColor ? {} : { level: 1 });
2122
const { bold, red, yellow } = chalkCtx;
2223

24+
2325
export enum MESSAGE_KIND {
2426
Init,
2527
Update
@@ -46,43 +48,9 @@ export class UpdateMessage extends TypeCheckerMessage {
4648
}
4749
}
4850

49-
let typeChecker: TypeChecker;
50-
let lastCancellationToken: CancellationToken;
51-
52-
process.on('message', (message: TypeCheckerMessage) => {
53-
time('TypeChecker.message');
54-
switch (message.kind) {
55-
case MESSAGE_KIND.Init:
56-
const initMessage = message as InitMessage;
57-
typeChecker = new TypeChecker(
58-
initMessage.compilerOptions,
59-
initMessage.basePath,
60-
initMessage.jitMode,
61-
initMessage.rootNames,
62-
);
63-
break;
64-
case MESSAGE_KIND.Update:
65-
if (!typeChecker) {
66-
throw new Error('TypeChecker: update message received before initialization');
67-
}
68-
if (lastCancellationToken) {
69-
// This cancellation token doesn't seem to do much, messages don't seem to be processed
70-
// before the diagnostics finish.
71-
lastCancellationToken.requestCancellation();
72-
}
73-
const updateMessage = message as UpdateMessage;
74-
lastCancellationToken = new CancellationToken();
75-
typeChecker.update(updateMessage.rootNames, updateMessage.changedCompilationFiles,
76-
lastCancellationToken);
77-
break;
78-
default:
79-
throw new Error(`TypeChecker: Unexpected message received: ${message}.`);
80-
}
81-
timeEnd('TypeChecker.message');
82-
});
83-
51+
export const AUTO_START_ARG = '9d93e901-158a-4cf9-ba1b-2f0582ffcfeb';
8452

85-
class TypeChecker {
53+
export class TypeChecker {
8654
private _program: ts.Program | Program;
8755
private _compilerHost: WebpackCompilerHost & CompilerHost;
8856

@@ -171,3 +139,4 @@ class TypeChecker {
171139
this._diagnose(cancellationToken);
172140
}
173141
}
142+
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
require('../../../../lib/bootstrap-local');
2-
require('./type_checker.ts');
2+
require('./type_checker_worker.ts');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as process from 'process';
2+
3+
import { time, timeEnd } from './benchmark';
4+
import { CancellationToken } from './gather_diagnostics';
5+
6+
import {
7+
AUTO_START_ARG,
8+
TypeCheckerMessage,
9+
InitMessage,
10+
MESSAGE_KIND,
11+
UpdateMessage,
12+
TypeChecker
13+
} from './type_checker';
14+
15+
let typeChecker: TypeChecker;
16+
let lastCancellationToken: CancellationToken;
17+
18+
// only listen to messages if started from the AngularCompilerPlugin
19+
if (process.argv.indexOf(AUTO_START_ARG) >= 0) {
20+
process.on('message', (message: TypeCheckerMessage) => {
21+
time('TypeChecker.message');
22+
switch (message.kind) {
23+
case MESSAGE_KIND.Init:
24+
const initMessage = message as InitMessage;
25+
typeChecker = new TypeChecker(
26+
initMessage.compilerOptions,
27+
initMessage.basePath,
28+
initMessage.jitMode,
29+
initMessage.rootNames,
30+
);
31+
break;
32+
case MESSAGE_KIND.Update:
33+
if (!typeChecker) {
34+
throw new Error('TypeChecker: update message received before initialization');
35+
}
36+
if (lastCancellationToken) {
37+
// This cancellation token doesn't seem to do much, messages don't seem to be processed
38+
// before the diagnostics finish.
39+
lastCancellationToken.requestCancellation();
40+
}
41+
const updateMessage = message as UpdateMessage;
42+
lastCancellationToken = new CancellationToken();
43+
typeChecker.update(updateMessage.rootNames, updateMessage.changedCompilationFiles,
44+
lastCancellationToken);
45+
break;
46+
default:
47+
throw new Error(`TypeChecker: Unexpected message received: ${message}.`);
48+
}
49+
timeEnd('TypeChecker.message');
50+
});
51+
}
52+
53+

0 commit comments

Comments
 (0)