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