You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
660 lines
29 KiB
660 lines
29 KiB
"use strict"; |
|
const path = require("path"); |
|
const process = require("process"); |
|
const childProcess = require("child_process"); |
|
const worker_rpc_1 = require("worker-rpc"); |
|
const semver = require("semver"); |
|
const chalk_1 = require("chalk"); |
|
const micromatch = require("micromatch"); |
|
const os = require("os"); |
|
const CancellationToken_1 = require("./CancellationToken"); |
|
const NormalizedMessage_1 = require("./NormalizedMessage"); |
|
const defaultFormatter_1 = require("./formatter/defaultFormatter"); |
|
const codeframeFormatter_1 = require("./formatter/codeframeFormatter"); |
|
const FsHelper_1 = require("./FsHelper"); |
|
const hooks_1 = require("./hooks"); |
|
const RpcTypes_1 = require("./RpcTypes"); |
|
const checkerPluginName = 'fork-ts-checker-webpack-plugin'; |
|
/** |
|
* ForkTsCheckerWebpackPlugin |
|
* Runs typescript type checker and linter (tslint) on separate process. |
|
* This speed-ups build a lot. |
|
* |
|
* Options description in README.md |
|
*/ |
|
class ForkTsCheckerWebpackPlugin { |
|
constructor(options) { |
|
this.tslint = false; |
|
this.eslint = false; |
|
this.eslintOptions = {}; |
|
this.tslintAutoFix = false; |
|
this.tsconfigPath = undefined; |
|
this.tslintPath = undefined; |
|
this.watchPaths = []; |
|
this.compiler = undefined; |
|
this.started = undefined; |
|
this.elapsed = undefined; |
|
this.cancellationToken = undefined; |
|
this.isWatching = false; |
|
this.checkDone = false; |
|
this.compilationDone = false; |
|
this.diagnostics = []; |
|
this.lints = []; |
|
this.eslintVersion = undefined; |
|
this.startAt = 0; |
|
this.nodeArgs = []; |
|
options = options || {}; |
|
this.options = Object.assign({}, options); |
|
this.watch = |
|
typeof options.watch === 'string' ? [options.watch] : options.watch || []; |
|
this.ignoreDiagnostics = options.ignoreDiagnostics || []; |
|
this.ignoreLints = options.ignoreLints || []; |
|
this.ignoreLintWarnings = options.ignoreLintWarnings === true; |
|
this.reportFiles = options.reportFiles || []; |
|
this.logger = options.logger || console; |
|
this.silent = options.silent === true; // default false |
|
this.async = options.async !== false; // default true |
|
this.checkSyntacticErrors = options.checkSyntacticErrors === true; // default false |
|
this.resolveModuleNameModule = options.resolveModuleNameModule; |
|
this.resolveTypeReferenceDirectiveModule = |
|
options.resolveTypeReferenceDirectiveModule; |
|
this.workersNumber = options.workers || ForkTsCheckerWebpackPlugin.ONE_CPU; |
|
this.memoryLimit = |
|
options.memoryLimit || ForkTsCheckerWebpackPlugin.DEFAULT_MEMORY_LIMIT; |
|
this.useColors = options.colors !== false; // default true |
|
this.colors = new chalk_1.default.constructor({ enabled: this.useColors }); |
|
this.formatter = |
|
options.formatter && typeof options.formatter === 'function' |
|
? options.formatter |
|
: ForkTsCheckerWebpackPlugin.createFormatter(options.formatter || 'default', options.formatterOptions || {}); |
|
this.emitCallback = this.createNoopEmitCallback(); |
|
this.doneCallback = this.createDoneCallback(); |
|
const { typescript, typescriptPath, typescriptVersion, tsconfig, compilerOptions } = this.validateTypeScript(options); |
|
this.typescript = typescript; |
|
this.typescriptPath = typescriptPath; |
|
this.typescriptVersion = typescriptVersion; |
|
this.tsconfig = tsconfig; |
|
this.compilerOptions = compilerOptions; |
|
if (options.eslint === true) { |
|
const { eslintVersion, eslintOptions } = this.validateEslint(options); |
|
this.eslint = true; |
|
this.eslintVersion = eslintVersion; |
|
this.eslintOptions = eslintOptions; |
|
} |
|
else { |
|
const { tslint, tslintVersion, tslintAutoFix } = this.validateTslint(options); |
|
this.tslint = tslint; |
|
this.tslintVersion = tslintVersion; |
|
this.tslintAutoFix = tslintAutoFix; |
|
} |
|
this.vue = options.vue === true; // default false |
|
this.useTypescriptIncrementalApi = |
|
options.useTypescriptIncrementalApi === undefined |
|
? semver.gte(this.typescriptVersion, '3.0.0') && !this.vue |
|
: options.useTypescriptIncrementalApi; |
|
this.measureTime = options.measureCompilationTime === true; |
|
if (this.measureTime) { |
|
// Node 8+ only |
|
this.performance = require('perf_hooks').performance; |
|
} |
|
} |
|
static getCompilerHooks(compiler) { |
|
return hooks_1.getForkTsCheckerWebpackPluginHooks(compiler); |
|
} |
|
validateTypeScript(options) { |
|
const typescriptPath = options.typescript || require.resolve('typescript'); |
|
const tsconfig = options.tsconfig || './tsconfig.json'; |
|
const compilerOptions = typeof options.compilerOptions === 'object' |
|
? options.compilerOptions |
|
: {}; |
|
let typescript, typescriptVersion; |
|
try { |
|
typescript = require(typescriptPath); |
|
typescriptVersion = typescript.version; |
|
} |
|
catch (_ignored) { |
|
throw new Error('When you use this plugin you must install `typescript`.'); |
|
} |
|
if (semver.lt(typescriptVersion, '2.1.0')) { |
|
throw new Error(`Cannot use current typescript version of ${typescriptVersion}, the minimum required version is 2.1.0`); |
|
} |
|
return { |
|
typescriptPath, |
|
typescript, |
|
typescriptVersion, |
|
tsconfig, |
|
compilerOptions |
|
}; |
|
} |
|
validateTslint(options) { |
|
const tslint = options.tslint |
|
? options.tslint === true |
|
? true |
|
: options.tslint |
|
: undefined; |
|
let tslintAutoFix, tslintVersion; |
|
try { |
|
tslintAutoFix = options.tslintAutoFix || false; |
|
tslintVersion = tslint |
|
? // tslint:disable-next-line:no-implicit-dependencies |
|
require('tslint').Linter.VERSION |
|
: undefined; |
|
} |
|
catch (_ignored) { |
|
throw new Error('When you use `tslint` option, make sure to install `tslint`.'); |
|
} |
|
if (tslintVersion && semver.lt(tslintVersion, '4.0.0')) { |
|
throw new Error(`Cannot use current tslint version of ${tslintVersion}, the minimum required version is 4.0.0`); |
|
} |
|
return { tslint, tslintAutoFix, tslintVersion }; |
|
} |
|
validateEslint(options) { |
|
let eslintVersion; |
|
const eslintOptions = typeof options.eslintOptions === 'object' ? options.eslintOptions : {}; |
|
try { |
|
eslintVersion = require('eslint').Linter.version; |
|
} |
|
catch (_ignored) { |
|
throw new Error('When you use `eslint` option, make sure to install `eslint`.'); |
|
} |
|
return { eslintVersion, eslintOptions }; |
|
} |
|
static createFormatter(type, options) { |
|
switch (type) { |
|
case 'default': |
|
return defaultFormatter_1.createDefaultFormatter(); |
|
case 'codeframe': |
|
return codeframeFormatter_1.createCodeframeFormatter(options); |
|
default: |
|
throw new Error('Unknown "' + type + '" formatter. Available are: default, codeframe.'); |
|
} |
|
} |
|
apply(compiler) { |
|
this.compiler = compiler; |
|
this.tsconfigPath = this.computeContextPath(this.tsconfig); |
|
this.tslintPath = |
|
typeof this.tslint === 'string' |
|
? this.computeContextPath(this.tslint) |
|
: undefined; |
|
this.watchPaths = this.watch.map(this.computeContextPath.bind(this)); |
|
// validate config |
|
const tsconfigOk = FsHelper_1.fileExistsSync(this.tsconfigPath); |
|
const tslintOk = !this.tslintPath || FsHelper_1.fileExistsSync(this.tslintPath); |
|
if (this.useTypescriptIncrementalApi && this.workersNumber !== 1) { |
|
throw new Error('Using typescript incremental compilation API ' + |
|
'is currently only allowed with a single worker.'); |
|
} |
|
// validate logger |
|
if (this.logger) { |
|
if (!this.logger.error || !this.logger.warn || !this.logger.info) { |
|
throw new Error("Invalid logger object - doesn't provide `error`, `warn` or `info` method."); |
|
} |
|
} |
|
if (tsconfigOk && tslintOk) { |
|
this.pluginStart(); |
|
this.pluginStop(); |
|
this.pluginCompile(); |
|
this.pluginEmit(); |
|
this.pluginDone(); |
|
} |
|
else { |
|
if (!tsconfigOk) { |
|
throw new Error('Cannot find "' + |
|
this.tsconfigPath + |
|
'" file. Please check webpack and ForkTsCheckerWebpackPlugin configuration. \n' + |
|
'Possible errors: \n' + |
|
' - wrong `context` directory in webpack configuration' + |
|
' (if `tsconfig` is not set or is a relative path in fork plugin configuration)\n' + |
|
' - wrong `tsconfig` path in fork plugin configuration' + |
|
' (should be a relative or absolute path)'); |
|
} |
|
if (!tslintOk) { |
|
throw new Error('Cannot find "' + |
|
this.tslintPath + |
|
'" file. Please check webpack and ForkTsCheckerWebpackPlugin configuration. \n' + |
|
'Possible errors: \n' + |
|
' - wrong `context` directory in webpack configuration' + |
|
' (if `tslint` is not set or is a relative path in fork plugin configuration)\n' + |
|
' - wrong `tslint` path in fork plugin configuration' + |
|
' (should be a relative or absolute path)\n' + |
|
' - `tslint` path is not set to false in fork plugin configuration' + |
|
' (if you want to disable tslint support)'); |
|
} |
|
} |
|
} |
|
computeContextPath(filePath) { |
|
return path.isAbsolute(filePath) |
|
? filePath |
|
: path.resolve(this.compiler.options.context, filePath); |
|
} |
|
pluginStart() { |
|
const run = (_compiler, callback) => { |
|
this.isWatching = false; |
|
callback(); |
|
}; |
|
const watchRun = (_compiler, callback) => { |
|
this.isWatching = true; |
|
callback(); |
|
}; |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
this.compiler.hooks.run.tapAsync(checkerPluginName, run); |
|
this.compiler.hooks.watchRun.tapAsync(checkerPluginName, watchRun); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.plugin('run', run); |
|
this.compiler.plugin('watch-run', watchRun); |
|
} |
|
} |
|
pluginStop() { |
|
const watchClose = () => { |
|
this.killService(); |
|
}; |
|
const done = (_stats) => { |
|
if (!this.isWatching) { |
|
this.killService(); |
|
} |
|
}; |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
this.compiler.hooks.watchClose.tap(checkerPluginName, watchClose); |
|
this.compiler.hooks.done.tap(checkerPluginName, done); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.plugin('watch-close', watchClose); |
|
this.compiler.plugin('done', done); |
|
} |
|
process.on('exit', () => { |
|
this.killService(); |
|
}); |
|
} |
|
pluginCompile() { |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler); |
|
this.compiler.hooks.compile.tap(checkerPluginName, () => { |
|
this.compilationDone = false; |
|
forkTsCheckerHooks.serviceBeforeStart.callAsync(() => { |
|
if (this.cancellationToken) { |
|
// request cancellation if there is not finished job |
|
this.cancellationToken.requestCancellation(); |
|
forkTsCheckerHooks.cancel.call(this.cancellationToken); |
|
} |
|
this.checkDone = false; |
|
this.started = process.hrtime(); |
|
// create new token for current job |
|
this.cancellationToken = new CancellationToken_1.CancellationToken(this.typescript); |
|
if (!this.service || !this.service.connected) { |
|
this.spawnService(); |
|
} |
|
try { |
|
if (this.measureTime) { |
|
this.startAt = this.performance.now(); |
|
} |
|
this.serviceRpc.rpc(RpcTypes_1.RUN, this.cancellationToken.toJSON()).then(result => { |
|
if (result) { |
|
this.handleServiceMessage(result); |
|
} |
|
}); |
|
} |
|
catch (error) { |
|
if (!this.silent && this.logger) { |
|
this.logger.error(this.colors.red('Cannot start checker service: ' + |
|
(error ? error.toString() : 'Unknown error'))); |
|
} |
|
forkTsCheckerHooks.serviceStartError.call(error); |
|
} |
|
}); |
|
}); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.plugin('compile', () => { |
|
this.compilationDone = false; |
|
this.compiler.applyPluginsAsync(hooks_1.legacyHookMap.serviceBeforeStart, () => { |
|
if (this.cancellationToken) { |
|
// request cancellation if there is not finished job |
|
this.cancellationToken.requestCancellation(); |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.cancel, this.cancellationToken); |
|
} |
|
this.checkDone = false; |
|
this.started = process.hrtime(); |
|
// create new token for current job |
|
this.cancellationToken = new CancellationToken_1.CancellationToken(this.typescript, undefined, undefined); |
|
if (!this.service || !this.service.connected) { |
|
this.spawnService(); |
|
} |
|
try { |
|
this.serviceRpc.rpc(RpcTypes_1.RUN, this.cancellationToken.toJSON()).then(result => { |
|
if (result) { |
|
this.handleServiceMessage(result); |
|
} |
|
}); |
|
} |
|
catch (error) { |
|
if (!this.silent && this.logger) { |
|
this.logger.error(this.colors.red('Cannot start checker service: ' + |
|
(error ? error.toString() : 'Unknown error'))); |
|
} |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.serviceStartError, error); |
|
} |
|
}); |
|
}); |
|
} |
|
} |
|
pluginEmit() { |
|
const emit = (compilation, callback) => { |
|
if (this.isWatching && this.async) { |
|
callback(); |
|
return; |
|
} |
|
this.emitCallback = this.createEmitCallback(compilation, callback); |
|
if (this.checkDone) { |
|
this.emitCallback(); |
|
} |
|
this.compilationDone = true; |
|
}; |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
this.compiler.hooks.emit.tapAsync(checkerPluginName, emit); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.plugin('emit', emit); |
|
} |
|
} |
|
pluginDone() { |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler); |
|
this.compiler.hooks.done.tap(checkerPluginName, (_stats) => { |
|
if (!this.isWatching || !this.async) { |
|
return; |
|
} |
|
if (this.checkDone) { |
|
this.doneCallback(); |
|
} |
|
else { |
|
if (this.compiler) { |
|
forkTsCheckerHooks.waiting.call(this.tslint !== undefined); |
|
} |
|
if (!this.silent && this.logger) { |
|
this.logger.info(this.tslint |
|
? 'Type checking and linting in progress...' |
|
: 'Type checking in progress...'); |
|
} |
|
} |
|
this.compilationDone = true; |
|
}); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.plugin('done', () => { |
|
if (!this.isWatching || !this.async) { |
|
return; |
|
} |
|
if (this.checkDone) { |
|
this.doneCallback(); |
|
} |
|
else { |
|
if (this.compiler) { |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.waiting, this.tslint !== undefined); |
|
} |
|
if (!this.silent && this.logger) { |
|
this.logger.info(this.tslint |
|
? 'Type checking and linting in progress...' |
|
: 'Type checking in progress...'); |
|
} |
|
} |
|
this.compilationDone = true; |
|
}); |
|
} |
|
} |
|
spawnService() { |
|
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) }); |
|
if (typeof this.resolveModuleNameModule !== 'undefined') { |
|
env.RESOLVE_MODULE_NAME = this.resolveModuleNameModule; |
|
} |
|
else { |
|
delete env.RESOLVE_MODULE_NAME; |
|
} |
|
if (typeof this.resolveTypeReferenceDirectiveModule !== 'undefined') { |
|
env.RESOLVE_TYPE_REFERENCE_DIRECTIVE = this.resolveTypeReferenceDirectiveModule; |
|
} |
|
else { |
|
delete env.RESOLVE_TYPE_REFERENCE_DIRECTIVE; |
|
} |
|
this.service = childProcess.fork(path.resolve(__dirname, this.workersNumber > 1 ? './cluster.js' : './service.js'), [], { |
|
env, |
|
execArgv: (this.workersNumber > 1 |
|
? [] |
|
: ['--max-old-space-size=' + this.memoryLimit]).concat(this.nodeArgs), |
|
stdio: ['inherit', 'inherit', 'inherit', 'ipc'] |
|
}); |
|
this.serviceRpc = new worker_rpc_1.RpcProvider(message => this.service.send(message)); |
|
this.service.on('message', message => this.serviceRpc.dispatch(message)); |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler); |
|
forkTsCheckerHooks.serviceStart.call(this.tsconfigPath, this.tslintPath, this.watchPaths, this.workersNumber, this.memoryLimit); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.serviceStart, this.tsconfigPath, this.tslintPath, this.watchPaths, this.workersNumber, this.memoryLimit); |
|
} |
|
if (!this.silent && this.logger) { |
|
this.logger.info('Starting type checking' + |
|
(this.tslint ? ' and linting' : '') + |
|
' service...'); |
|
this.logger.info('Using ' + |
|
this.colors.bold(this.workersNumber === 1 |
|
? '1 worker' |
|
: this.workersNumber + ' workers') + |
|
' with ' + |
|
this.colors.bold(this.memoryLimit + 'MB') + |
|
' memory limit'); |
|
if (this.watchPaths.length && this.isWatching) { |
|
this.logger.info('Watching:' + |
|
(this.watchPaths.length > 1 ? '\n' : ' ') + |
|
this.watchPaths.map(wpath => this.colors.grey(wpath)).join('\n')); |
|
} |
|
} |
|
this.service.on('exit', (code, signal) => this.handleServiceExit(code, signal)); |
|
} |
|
killService() { |
|
if (!this.service) { |
|
return; |
|
} |
|
try { |
|
if (this.cancellationToken) { |
|
this.cancellationToken.cleanupCancellation(); |
|
} |
|
this.service.kill(); |
|
this.service = undefined; |
|
this.serviceRpc = undefined; |
|
} |
|
catch (e) { |
|
if (this.logger && !this.silent) { |
|
this.logger.error(e); |
|
} |
|
} |
|
} |
|
handleServiceMessage(message) { |
|
if (this.measureTime) { |
|
const delta = this.performance.now() - this.startAt; |
|
const deltaRounded = Math.round(delta * 100) / 100; |
|
this.logger.info(`Compilation took: ${deltaRounded} ms.`); |
|
} |
|
if (this.cancellationToken) { |
|
this.cancellationToken.cleanupCancellation(); |
|
// job is done - nothing to cancel |
|
this.cancellationToken = undefined; |
|
} |
|
this.checkDone = true; |
|
this.elapsed = process.hrtime(this.started); |
|
this.diagnostics = message.diagnostics.map(NormalizedMessage_1.NormalizedMessage.createFromJSON); |
|
this.lints = message.lints.map(NormalizedMessage_1.NormalizedMessage.createFromJSON); |
|
if (this.ignoreDiagnostics.length) { |
|
this.diagnostics = this.diagnostics.filter(diagnostic => !this.ignoreDiagnostics.includes(parseInt(diagnostic.code, 10))); |
|
} |
|
if (this.ignoreLints.length) { |
|
this.lints = this.lints.filter(lint => !this.ignoreLints.includes(lint.code)); |
|
} |
|
if (this.reportFiles.length) { |
|
const reportFilesPredicate = (diagnostic) => { |
|
if (diagnostic.file) { |
|
const relativeFileName = path.relative(this.compiler.options.context, diagnostic.file); |
|
const matchResult = micromatch([relativeFileName], this.reportFiles); |
|
if (matchResult.length === 0) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
}; |
|
this.diagnostics = this.diagnostics.filter(reportFilesPredicate); |
|
this.lints = this.lints.filter(reportFilesPredicate); |
|
} |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler); |
|
forkTsCheckerHooks.receive.call(this.diagnostics, this.lints); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.receive, this.diagnostics, this.lints); |
|
} |
|
if (this.compilationDone) { |
|
this.isWatching && this.async ? this.doneCallback() : this.emitCallback(); |
|
} |
|
} |
|
handleServiceExit(_code, signal) { |
|
if (signal !== 'SIGABRT') { |
|
return; |
|
} |
|
// probably out of memory :/ |
|
if (this.compiler) { |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler); |
|
forkTsCheckerHooks.serviceOutOfMemory.call(); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.serviceOutOfMemory); |
|
} |
|
} |
|
if (!this.silent && this.logger) { |
|
this.logger.error(this.colors.red('Type checking and linting aborted - probably out of memory. ' + |
|
'Check `memoryLimit` option in ForkTsCheckerWebpackPlugin configuration.')); |
|
} |
|
} |
|
createEmitCallback(compilation, callback) { |
|
return function emitCallback() { |
|
if (!this.elapsed) { |
|
throw new Error('Execution order error'); |
|
} |
|
const elapsed = Math.round(this.elapsed[0] * 1e9 + this.elapsed[1]); |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler); |
|
forkTsCheckerHooks.emit.call(this.diagnostics, this.lints, elapsed); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.emit, this.diagnostics, this.lints, elapsed); |
|
} |
|
this.diagnostics.concat(this.lints).forEach(message => { |
|
// webpack message format |
|
const formatted = { |
|
rawMessage: message.severity.toUpperCase() + |
|
' ' + |
|
message.getFormattedCode() + |
|
': ' + |
|
message.content, |
|
message: this.formatter(message, this.useColors), |
|
location: { |
|
line: message.line, |
|
character: message.character |
|
}, |
|
file: message.file |
|
}; |
|
if (message.isWarningSeverity()) { |
|
if (!this.ignoreLintWarnings) { |
|
compilation.warnings.push(formatted); |
|
} |
|
} |
|
else { |
|
compilation.errors.push(formatted); |
|
} |
|
}); |
|
callback(); |
|
}; |
|
} |
|
createNoopEmitCallback() { |
|
// tslint:disable-next-line:no-empty |
|
return function noopEmitCallback() { }; |
|
} |
|
printLoggerMessage(message, formattedMessage) { |
|
if (message.isWarningSeverity()) { |
|
if (this.ignoreLintWarnings) { |
|
return; |
|
} |
|
this.logger.warn(formattedMessage); |
|
} |
|
else { |
|
this.logger.error(formattedMessage); |
|
} |
|
} |
|
createDoneCallback() { |
|
return function doneCallback() { |
|
if (!this.elapsed) { |
|
throw new Error('Execution order error'); |
|
} |
|
const elapsed = Math.round(this.elapsed[0] * 1e9 + this.elapsed[1]); |
|
if (this.compiler) { |
|
if ('hooks' in this.compiler) { |
|
// webpack 4+ |
|
const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(this.compiler); |
|
forkTsCheckerHooks.done.call(this.diagnostics, this.lints, elapsed); |
|
} |
|
else { |
|
// webpack 2 / 3 |
|
this.compiler.applyPlugins(hooks_1.legacyHookMap.done, this.diagnostics, this.lints, elapsed); |
|
} |
|
} |
|
if (!this.silent && this.logger) { |
|
if (this.diagnostics.length || this.lints.length) { |
|
(this.lints || []).concat(this.diagnostics).forEach(message => { |
|
const formattedMessage = this.formatter(message, this.useColors); |
|
this.printLoggerMessage(message, formattedMessage); |
|
}); |
|
} |
|
if (!this.diagnostics.length) { |
|
this.logger.info(this.colors.green('No type errors found')); |
|
} |
|
if (this.tslint && !this.lints.length) { |
|
this.logger.info(this.colors.green('No lint errors found')); |
|
} |
|
this.logger.info('Version: typescript ' + |
|
this.colors.bold(this.typescriptVersion) + |
|
(this.eslint |
|
? ', eslint ' + this.colors.bold(this.eslintVersion) |
|
: this.tslint |
|
? ', tslint ' + this.colors.bold(this.tslintVersion) |
|
: '')); |
|
this.logger.info('Time: ' + |
|
this.colors.bold(Math.round(elapsed / 1e6).toString()) + |
|
'ms'); |
|
} |
|
}; |
|
} |
|
} |
|
ForkTsCheckerWebpackPlugin.DEFAULT_MEMORY_LIMIT = 2048; |
|
ForkTsCheckerWebpackPlugin.ONE_CPU = 1; |
|
ForkTsCheckerWebpackPlugin.ALL_CPUS = os.cpus && os.cpus() ? os.cpus().length : 1; |
|
ForkTsCheckerWebpackPlugin.ONE_CPU_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 1); |
|
ForkTsCheckerWebpackPlugin.TWO_CPUS_FREE = Math.max(1, ForkTsCheckerWebpackPlugin.ALL_CPUS - 2); |
|
module.exports = ForkTsCheckerWebpackPlugin; |
|
//# sourceMappingURL=index.js.map
|