UNPKG

29.3 kBJavaScriptView Raw
1"use strict";
2const path = require("path");
3const process = require("process");
4const childProcess = require("child_process");
5const worker_rpc_1 = require("worker-rpc");
6const semver = require("semver");
7const chalk_1 = require("chalk");
8const micromatch = require("micromatch");
9const os = require("os");
10const CancellationToken_1 = require("./CancellationToken");
11const NormalizedMessage_1 = require("./NormalizedMessage");
12const defaultFormatter_1 = require("./formatter/defaultFormatter");
13const codeframeFormatter_1 = require("./formatter/codeframeFormatter");
14const FsHelper_1 = require("./FsHelper");
15const hooks_1 = require("./hooks");
16const RpcTypes_1 = require("./RpcTypes");
17const checkerPluginName = 'fork-ts-checker-webpack-plugin';
18/**
19 * ForkTsCheckerWebpackPlugin
20 * Runs typescript type checker and linter (tslint) on separate process.
21 * This speed-ups build a lot.
22 *
23 * Options description in README.md
24 */
25class ForkTsCheckerWebpackPlugin {
26 constructor(options) {
27 this.tslint = false;
28 this.eslint = false;
29 this.eslintOptions = {};
30 this.tslintAutoFix = false;
31 this.tsconfigPath = undefined;
32 this.tslintPath = undefined;
33 this.watchPaths = [];
34 this.compiler = undefined;
35 this.started = undefined;
36 this.elapsed = undefined;
37 this.cancellationToken = undefined;
38 this.isWatching = false;
39 this.checkDone = false;
40 this.compilationDone = false;
41 this.diagnostics = [];
42 this.lints = [];
43 this.eslintVersion = undefined;
44 this.startAt = 0;
45 this.nodeArgs = [];
46 options = options || {};
47 this.options = Object.assign({}, options);
48 this.watch =
49 typeof options.watch === 'string' ? [options.watch] : options.watch || [];
50 this.ignoreDiagnostics = options.ignoreDiagnostics || [];
51 this.ignoreLints = options.ignoreLints || [];
52 this.ignoreLintWarnings = options.ignoreLintWarnings === true;
53 this.reportFiles = options.reportFiles || [];
54 this.logger = options.logger || console;
55 this.silent = options.silent === true; // default false
56 this.async = options.async !== false; // default true
57 this.checkSyntacticErrors = options.checkSyntacticErrors === true; // default false
58 this.resolveModuleNameModule = options.resolveModuleNameModule;
59 this.resolveTypeReferenceDirectiveModule =
60 options.resolveTypeReferenceDirectiveModule;
61 this.workersNumber = options.workers || ForkTsCheckerWebpackPlugin.ONE_CPU;
62 this.memoryLimit =
63 options.memoryLimit || ForkTsCheckerWebpackPlugin.DEFAULT_MEMORY_LIMIT;
64 this.useColors = options.colors !== false; // default true
65 this.colors = new chalk_1.default.constructor({ enabled: this.useColors });
66 this.formatter =
67 options.formatter && typeof options.formatter === 'function'
68 ? options.formatter
69 : ForkTsCheckerWebpackPlugin.createFormatter(options.formatter || 'default', options.formatterOptions || {});
70 this.emitCallback = this.createNoopEmitCallback();
71 this.doneCallback = this.createDoneCallback();
72 const { typescript, typescriptPath, typescriptVersion, tsconfig, compilerOptions } = this.validateTypeScript(options);
73 this.typescript = typescript;
74 this.typescriptPath = typescriptPath;
75 this.typescriptVersion = typescriptVersion;
76 this.tsconfig = tsconfig;
77 this.compilerOptions = compilerOptions;
78 if (options.eslint === true) {
79 const { eslintVersion, eslintOptions } = this.validateEslint(options);
80 this.eslint = true;
81 this.eslintVersion = eslintVersion;
82 this.eslintOptions = eslintOptions;
83 }
84 else {
85 const { tslint, tslintVersion, tslintAutoFix } = this.validateTslint(options);
86 this.tslint = tslint;
87 this.tslintVersion = tslintVersion;
88 this.tslintAutoFix = tslintAutoFix;
89 }
90 this.vue = options.vue === true; // default false
91 this.useTypescriptIncrementalApi =
92 options.useTypescriptIncrementalApi === undefined
93 ? semver.gte(this.typescriptVersion, '3.0.0') && !this.vue
94 : options.useTypescriptIncrementalApi;
95 this.measureTime = options.measureCompilationTime === true;
96 if (this.measureTime) {
97 // Node 8+ only
98 this.performance = require('perf_hooks').performance;
99 }
100 }
101 static getCompilerHooks(compiler) {
102 return hooks_1.getForkTsCheckerWebpackPluginHooks(compiler);
103 }
104 validateTypeScript(options) {
105 const typescriptPath = options.typescript || require.resolve('typescript');
106 const tsconfig = options.tsconfig || './tsconfig.json';
107 const compilerOptions = typeof options.compilerOptions === 'object'
108 ? options.compilerOptions
109 : {};
110 let typescript, typescriptVersion;
111 try {
112 typescript = require(typescriptPath);
113 typescriptVersion = typescript.version;
114 }
115 catch (_ignored) {
116 throw new Error('When you use this plugin you must install `typescript`.');
117 }
118 if (semver.lt(typescriptVersion, '2.1.0')) {
119 throw new Error(`Cannot use current typescript version of ${typescriptVersion}, the minimum required version is 2.1.0`);
120 }
121 return {
122 typescriptPath,
123 typescript,
124 typescriptVersion,
125 tsconfig,
126 compilerOptions
127 };
128 }
129 validateTslint(options) {
130 const tslint = options.tslint
131 ? options.tslint === true
132 ? true
133 : options.tslint
134 : undefined;
135 let tslintAutoFix, tslintVersion;
136 try {
137 tslintAutoFix = options.tslintAutoFix || false;
138 tslintVersion = tslint
139 ? // tslint:disable-next-line:no-implicit-dependencies
140 require('tslint').Linter.VERSION
141 : undefined;
142 }
143 catch (_ignored) {
144 throw new Error('When you use `tslint` option, make sure to install `tslint`.');
145 }
146 if (tslintVersion && semver.lt(tslintVersion, '4.0.0')) {
147 throw new Error(`Cannot use current tslint version of ${tslintVersion}, the minimum required version is 4.0.0`);
148 }
149 return { tslint, tslintAutoFix, tslintVersion };
150 }
151 validateEslint(options) {
152 let eslintVersion;
153 const eslintOptions = typeof options.eslintOptions === 'object' ? options.eslintOptions : {};
154 try {
155 eslintVersion = require('eslint').Linter.version;
156 }
157 catch (_ignored) {
158 throw new Error('When you use `eslint` option, make sure to install `eslint`.');
159 }
160 return { eslintVersion, eslintOptions };
161 }
162 static createFormatter(type, options) {
163 switch (type) {
164 case 'default':
165 return defaultFormatter_1.createDefaultFormatter();
166 case 'codeframe':
167 return codeframeFormatter_1.createCodeframeFormatter(options);
168 default:
169 throw new Error('Unknown "' + type + '" formatter. Available are: default, codeframe.');
170 }
171 }
172 apply(compiler) {
173 this.compiler = compiler;
174 this.tsconfigPath = this.computeContextPath(this.tsconfig);
175 this.tslintPath =
176 typeof this.tslint === 'string'
177 ? this.computeContextPath(this.tslint)
178 : undefined;
179 this.watchPaths = this.watch.map(this.computeContextPath.bind(this));
180 // validate config
181 const tsconfigOk = FsHelper_1.fileExistsSync(this.tsconfigPath);
182 const tslintOk = !this.tslintPath || FsHelper_1.fileExistsSync(this.tslintPath);
183 if (this.useTypescriptIncrementalApi && this.workersNumber !== 1) {
184 throw new Error('Using typescript incremental compilation API ' +
185 'is currently only allowed with a single worker.');
186 }
187 // validate logger
188 if (this.logger) {
189 if (!this.logger.error || !this.logger.warn || !this.logger.info) {
190 throw new Error("Invalid logger object - doesn't provide `error`, `warn` or `info` method.");
191 }
192 }
193 if (tsconfigOk && tslintOk) {
194 this.pluginStart();
195 this.pluginStop();
196 this.pluginCompile();
197 this.pluginEmit();
198 this.pluginDone();
199 }
200 else {
201 if (!tsconfigOk) {
202 throw new Error('Cannot find "' +
203 this.tsconfigPath +
204 '" file. Please check webpack and ForkTsCheckerWebpackPlugin configuration. \n' +
205 'Possible errors: \n' +
206 ' - wrong `context` directory in webpack configuration' +
207 ' (if `tsconfig` is not set or is a relative path in fork plugin configuration)\n' +
208 ' - wrong `tsconfig` path in fork plugin configuration' +
209 ' (should be a relative or absolute path)');
210 }
211 if (!tslintOk) {
212 throw new Error('Cannot find "' +
213 this.tslintPath +
214 '" file. Please check webpack and ForkTsCheckerWebpackPlugin configuration. \n' +
215 'Possible errors: \n' +
216 ' - wrong `context` directory in webpack configuration' +
217 ' (if `tslint` is not set or is a relative path in fork plugin configuration)\n' +
218 ' - wrong `tslint` path in fork plugin configuration' +
219 ' (should be a relative or absolute path)\n' +
220 ' - `tslint` path is not set to false in fork plugin configuration' +
221 ' (if you want to disable tslint support)');
222 }
223 }
224 }
225 computeContextPath(filePath) {
226 return path.isAbsolute(filePath)
227 ? filePath
228 : path.resolve(this.compiler.options.context, filePath);
229 }
230 pluginStart() {
231 const run = (_compiler, callback) => {
232 this.isWatching = false;
233 callback();
234 };
235 const watchRun = (_compiler, callback) => {
236 this.isWatching = true;
237 callback();
238 };
239 if ('hooks' in this.compiler) {
240 // webpack 4+
241 this.compiler.hooks.run.tapAsync(checkerPluginName, run);
242 this.compiler.hooks.watchRun.tapAsync(checkerPluginName, watchRun);
243 }
244 else {
245 // webpack 2 / 3
246 this.compiler.plugin('run', run);
247 this.compiler.plugin('watch-run', watchRun);
248 }
249 }
250 pluginStop() {
251 const watchClose = () => {
252 this.killService();
253 };
254 const done = (_stats) => {
255 if (!this.isWatching) {
256 this.killService();
257 }
258 };
259 if ('hooks' in this.compiler) {
260 // webpack 4+
261 this.compiler.hooks.watchClose.tap(checkerPluginName, watchClose);
262 this.compiler.hooks.done.tap(checkerPluginName, done);
263 }
264 else {
265 // webpack 2 / 3
266 this.compiler.plugin('watch-close', watchClose);
267 this.compiler.plugin('done', done);
268 }
269 process.on('exit', () => {
270 this.killService();
271 });
272 }
273 pluginCompile() {
274 if ('hooks' in this.compiler) {
275 // webpack 4+
276 const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler);
277 this.compiler.hooks.compile.tap(checkerPluginName, () => {
278 this.compilationDone = false;
279 forkTsCheckerHooks.serviceBeforeStart.callAsync(() => {
280 if (this.cancellationToken) {
281 // request cancellation if there is not finished job
282 this.cancellationToken.requestCancellation();
283 forkTsCheckerHooks.cancel.call(this.cancellationToken);
284 }
285 this.checkDone = false;
286 this.started = process.hrtime();
287 // create new token for current job
288 this.cancellationToken = new CancellationToken_1.CancellationToken(this.typescript);
289 if (!this.service || !this.service.connected) {
290 this.spawnService();
291 }
292 try {
293 if (this.measureTime) {
294 this.startAt = this.performance.now();
295 }
296 this.serviceRpc.rpc(RpcTypes_1.RUN, this.cancellationToken.toJSON()).then(result => {
297 if (result) {
298 this.handleServiceMessage(result);
299 }
300 });
301 }
302 catch (error) {
303 if (!this.silent && this.logger) {
304 this.logger.error(this.colors.red('Cannot start checker service: ' +
305 (error ? error.toString() : 'Unknown error')));
306 }
307 forkTsCheckerHooks.serviceStartError.call(error);
308 }
309 });
310 });
311 }
312 else {
313 // webpack 2 / 3
314 this.compiler.plugin('compile', () => {
315 this.compilationDone = false;
316 this.compiler.applyPluginsAsync(hooks_1.legacyHookMap.serviceBeforeStart, () => {
317 if (this.cancellationToken) {
318 // request cancellation if there is not finished job
319 this.cancellationToken.requestCancellation();
320 this.compiler.applyPlugins(hooks_1.legacyHookMap.cancel, this.cancellationToken);
321 }
322 this.checkDone = false;
323 this.started = process.hrtime();
324 // create new token for current job
325 this.cancellationToken = new CancellationToken_1.CancellationToken(this.typescript, undefined, undefined);
326 if (!this.service || !this.service.connected) {
327 this.spawnService();
328 }
329 try {
330 this.serviceRpc.rpc(RpcTypes_1.RUN, this.cancellationToken.toJSON()).then(result => {
331 if (result) {
332 this.handleServiceMessage(result);
333 }
334 });
335 }
336 catch (error) {
337 if (!this.silent && this.logger) {
338 this.logger.error(this.colors.red('Cannot start checker service: ' +
339 (error ? error.toString() : 'Unknown error')));
340 }
341 this.compiler.applyPlugins(hooks_1.legacyHookMap.serviceStartError, error);
342 }
343 });
344 });
345 }
346 }
347 pluginEmit() {
348 const emit = (compilation, callback) => {
349 if (this.isWatching && this.async) {
350 callback();
351 return;
352 }
353 this.emitCallback = this.createEmitCallback(compilation, callback);
354 if (this.checkDone) {
355 this.emitCallback();
356 }
357 this.compilationDone = true;
358 };
359 if ('hooks' in this.compiler) {
360 // webpack 4+
361 this.compiler.hooks.afterCompile.tapAsync(checkerPluginName, emit);
362 }
363 else {
364 // webpack 2 / 3
365 this.compiler.plugin('emit', emit);
366 }
367 }
368 pluginDone() {
369 if ('hooks' in this.compiler) {
370 // webpack 4+
371 const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler);
372 this.compiler.hooks.done.tap(checkerPluginName, (_stats) => {
373 if (!this.isWatching || !this.async) {
374 return;
375 }
376 if (this.checkDone) {
377 this.doneCallback();
378 }
379 else {
380 if (this.compiler) {
381 forkTsCheckerHooks.waiting.call(this.tslint !== undefined);
382 }
383 if (!this.silent && this.logger) {
384 this.logger.info(this.tslint
385 ? 'Type checking and linting in progress...'
386 : 'Type checking in progress...');
387 }
388 }
389 this.compilationDone = true;
390 });
391 }
392 else {
393 // webpack 2 / 3
394 this.compiler.plugin('done', () => {
395 if (!this.isWatching || !this.async) {
396 return;
397 }
398 if (this.checkDone) {
399 this.doneCallback();
400 }
401 else {
402 if (this.compiler) {
403 this.compiler.applyPlugins(hooks_1.legacyHookMap.waiting, this.tslint !== undefined);
404 }
405 if (!this.silent && this.logger) {
406 this.logger.info(this.tslint
407 ? 'Type checking and linting in progress...'
408 : 'Type checking in progress...');
409 }
410 }
411 this.compilationDone = true;
412 });
413 }
414 }
415 spawnService() {
416 const env = Object.assign({}, process.env, { TYPESCRIPT_PATH: this.typescriptPath, TSCONFIG: this.tsconfigPath, COMPILER_OPTIONS: JSON.stringify(this.compilerOptions), TSLINT: this.tslintPath || (this.tslint ? 'true' : ''), CONTEXT: this.compiler.options.context, TSLINTAUTOFIX: String(this.tslintAutoFix), ESLINT: String(this.eslint), ESLINT_OPTIONS: JSON.stringify(this.eslintOptions), WATCH: this.isWatching ? this.watchPaths.join('|') : '', WORK_DIVISION: String(Math.max(1, this.workersNumber)), MEMORY_LIMIT: String(this.memoryLimit), CHECK_SYNTACTIC_ERRORS: String(this.checkSyntacticErrors), USE_INCREMENTAL_API: String(this.useTypescriptIncrementalApi === true), VUE: String(this.vue) });
417 if (typeof this.resolveModuleNameModule !== 'undefined') {
418 env.RESOLVE_MODULE_NAME = this.resolveModuleNameModule;
419 }
420 else {
421 delete env.RESOLVE_MODULE_NAME;
422 }
423 if (typeof this.resolveTypeReferenceDirectiveModule !== 'undefined') {
424 env.RESOLVE_TYPE_REFERENCE_DIRECTIVE = this.resolveTypeReferenceDirectiveModule;
425 }
426 else {
427 delete env.RESOLVE_TYPE_REFERENCE_DIRECTIVE;
428 }
429 this.service = childProcess.fork(path.resolve(__dirname, this.workersNumber > 1 ? './cluster.js' : './service.js'), [], {
430 env,
431 execArgv: (this.workersNumber > 1
432 ? []
433 : ['--max-old-space-size=' + this.memoryLimit]).concat(this.nodeArgs),
434 stdio: ['inherit', 'inherit', 'inherit', 'ipc']
435 });
436 this.serviceRpc = new worker_rpc_1.RpcProvider(message => this.service.send(message));
437 this.service.on('message', message => this.serviceRpc.dispatch(message));
438 if ('hooks' in this.compiler) {
439 // webpack 4+
440 const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler);
441 forkTsCheckerHooks.serviceStart.call(this.tsconfigPath, this.tslintPath, this.watchPaths, this.workersNumber, this.memoryLimit);
442 }
443 else {
444 // webpack 2 / 3
445 this.compiler.applyPlugins(hooks_1.legacyHookMap.serviceStart, this.tsconfigPath, this.tslintPath, this.watchPaths, this.workersNumber, this.memoryLimit);
446 }
447 if (!this.silent && this.logger) {
448 this.logger.info('Starting type checking' +
449 (this.tslint ? ' and linting' : '') +
450 ' service...');
451 this.logger.info('Using ' +
452 this.colors.bold(this.workersNumber === 1
453 ? '1 worker'
454 : this.workersNumber + ' workers') +
455 ' with ' +
456 this.colors.bold(this.memoryLimit + 'MB') +
457 ' memory limit');
458 if (this.watchPaths.length && this.isWatching) {
459 this.logger.info('Watching:' +
460 (this.watchPaths.length > 1 ? '\n' : ' ') +
461 this.watchPaths.map(wpath => this.colors.grey(wpath)).join('\n'));
462 }
463 }
464 this.service.on('exit', (code, signal) => this.handleServiceExit(code, signal));
465 }
466 killService() {
467 if (!this.service) {
468 return;
469 }
470 try {
471 if (this.cancellationToken) {
472 this.cancellationToken.cleanupCancellation();
473 }
474 this.service.kill();
475 this.service = undefined;
476 this.serviceRpc = undefined;
477 }
478 catch (e) {
479 if (this.logger && !this.silent) {
480 this.logger.error(e);
481 }
482 }
483 }
484 handleServiceMessage(message) {
485 if (this.measureTime) {
486 const delta = this.performance.now() - this.startAt;
487 const deltaRounded = Math.round(delta * 100) / 100;
488 this.logger.info(`Compilation took: ${deltaRounded} ms.`);
489 }
490 if (this.cancellationToken) {
491 this.cancellationToken.cleanupCancellation();
492 // job is done - nothing to cancel
493 this.cancellationToken = undefined;
494 }
495 this.checkDone = true;
496 this.elapsed = process.hrtime(this.started);
497 this.diagnostics = message.diagnostics.map(NormalizedMessage_1.NormalizedMessage.createFromJSON);
498 this.lints = message.lints.map(NormalizedMessage_1.NormalizedMessage.createFromJSON);
499 if (this.ignoreDiagnostics.length) {
500 this.diagnostics = this.diagnostics.filter(diagnostic => !this.ignoreDiagnostics.includes(parseInt(diagnostic.code, 10)));
501 }
502 if (this.ignoreLints.length) {
503 this.lints = this.lints.filter(lint => !this.ignoreLints.includes(lint.code));
504 }
505 if (this.reportFiles.length) {
506 const reportFilesPredicate = (diagnostic) => {
507 if (diagnostic.file) {
508 const relativeFileName = path.relative(this.compiler.options.context, diagnostic.file);
509 const matchResult = micromatch([relativeFileName], this.reportFiles);
510 if (matchResult.length === 0) {
511 return false;
512 }
513 }
514 return true;
515 };
516 this.diagnostics = this.diagnostics.filter(reportFilesPredicate);
517 this.lints = this.lints.filter(reportFilesPredicate);
518 }
519 if ('hooks' in this.compiler) {
520 // webpack 4+
521 const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler);
522 forkTsCheckerHooks.receive.call(this.diagnostics, this.lints);
523 }
524 else {
525 // webpack 2 / 3
526 this.compiler.applyPlugins(hooks_1.legacyHookMap.receive, this.diagnostics, this.lints);
527 }
528 if (this.compilationDone) {
529 this.isWatching && this.async ? this.doneCallback() : this.emitCallback();
530 }
531 }
532 handleServiceExit(_code, signal) {
533 if (signal !== 'SIGABRT') {
534 return;
535 }
536 // probably out of memory :/
537 if (this.compiler) {
538 if ('hooks' in this.compiler) {
539 // webpack 4+
540 const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler);
541 forkTsCheckerHooks.serviceOutOfMemory.call();
542 }
543 else {
544 // webpack 2 / 3
545 this.compiler.applyPlugins(hooks_1.legacyHookMap.serviceOutOfMemory);
546 }
547 }
548 if (!this.silent && this.logger) {
549 this.logger.error(this.colors.red('Type checking and linting aborted - probably out of memory. ' +
550 'Check `memoryLimit` option in ForkTsCheckerWebpackPlugin configuration.'));
551 }
552 }
553 createEmitCallback(compilation, callback) {
554 return function emitCallback() {
555 if (!this.elapsed) {
556 throw new Error('Execution order error');
557 }
558 const elapsed = Math.round(this.elapsed[0] * 1e9 + this.elapsed[1]);
559 if ('hooks' in this.compiler) {
560 // webpack 4+
561 const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler);
562 forkTsCheckerHooks.emit.call(this.diagnostics, this.lints, elapsed);
563 }
564 else {
565 // webpack 2 / 3
566 this.compiler.applyPlugins(hooks_1.legacyHookMap.emit, this.diagnostics, this.lints, elapsed);
567 }
568 this.diagnostics.concat(this.lints).forEach(message => {
569 // webpack message format
570 const formatted = {
571 rawMessage: message.severity.toUpperCase() +
572 ' ' +
573 message.getFormattedCode() +
574 ': ' +
575 message.content,
576 message: this.formatter(message, this.useColors),
577 location: {
578 line: message.line,
579 character: message.character
580 },
581 file: message.file
582 };
583 if (message.isWarningSeverity()) {
584 if (!this.ignoreLintWarnings) {
585 compilation.warnings.push(formatted);
586 }
587 }
588 else {
589 compilation.errors.push(formatted);
590 }
591 });
592 callback();
593 };
594 }
595 createNoopEmitCallback() {
596 // tslint:disable-next-line:no-empty
597 return function noopEmitCallback() { };
598 }
599 printLoggerMessage(message, formattedMessage) {
600 if (message.isWarningSeverity()) {
601 if (this.ignoreLintWarnings) {
602 return;
603 }
604 this.logger.warn(formattedMessage);
605 }
606 else {
607 this.logger.error(formattedMessage);
608 }
609 }
610 createDoneCallback() {
611 return function doneCallback() {
612 if (!this.elapsed) {
613 throw new Error('Execution order error');
614 }
615 const elapsed = Math.round(this.elapsed[0] * 1e9 + this.elapsed[1]);
616 if (this.compiler) {
617 if ('hooks' in this.compiler) {
618 // webpack 4+
619 const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler);
620 forkTsCheckerHooks.done.call(this.diagnostics, this.lints, elapsed);
621 }
622 else {
623 // webpack 2 / 3
624 this.compiler.applyPlugins(hooks_1.legacyHookMap.done, this.diagnostics, this.lints, elapsed);
625 }
626 }
627 if (!this.silent && this.logger) {
628 if (this.diagnostics.length || this.lints.length) {
629 (this.lints || []).concat(this.diagnostics).forEach(message => {
630 const formattedMessage = this.formatter(message, this.useColors);
631 this.printLoggerMessage(message, formattedMessage);
632 });
633 }
634 if (!this.diagnostics.length) {
635 this.logger.info(this.colors.green('No type errors found'));
636 }
637 if (this.tslint && !this.lints.length) {
638 this.logger.info(this.colors.green('No lint errors found'));
639 }
640 this.logger.info('Version: typescript ' +
641 this.colors.bold(this.typescriptVersion) +
642 (this.eslint
643 ? ', eslint ' + this.colors.bold(this.eslintVersion)
644 : this.tslint
645 ? ', tslint ' + this.colors.bold(this.tslintVersion)
646 : ''));
647 this.logger.info('Time: ' +
648 this.colors.bold(Math.round(elapsed / 1e6).toString()) +
649 'ms');
650 }
651 };
652 }
653}
654ForkTsCheckerWebpackPlugin.DEFAULT_MEMORY_LIMIT = 2048;
655ForkTsCheckerWebpackPlugin.ONE_CPU = 1;
656ForkTsCheckerWebpackPlugin.ALL_CPUS = os.cpus && os.cpus() ? os.cpus().length : 1;
657ForkTsCheckerWebpackPlugin.ONE_CPU_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 1);
658ForkTsCheckerWebpackPlugin.TWO_CPUS_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 2);
659module.exports = ForkTsCheckerWebpackPlugin;
660//# sourceMappingURL=index.js.map
\No newline at end of file