Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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