wallet-core/node_modules/ts-loader/dist/after-compile.js
2017-05-03 15:35:00 +02:00

148 lines
6.6 KiB
JavaScript

"use strict";
var path = require("path");
var utils = require("./utils");
var constants = require("./constants");
function makeAfterCompile(instance, configFilePath) {
var getCompilerOptionDiagnostics = true;
var checkAllFilesForErrors = true;
return function (compilation, callback) {
// Don't add errors for child compilations
if (compilation.compiler.isChild()) {
callback();
return;
}
removeTSLoaderErrors(compilation.errors);
provideCompilerOptionDiagnosticErrorsToWebpack(getCompilerOptionDiagnostics, compilation, instance, configFilePath);
getCompilerOptionDiagnostics = false;
var modules = determineModules(compilation);
var filesToCheckForErrors = determineFilesToCheckForErrors(checkAllFilesForErrors, instance);
checkAllFilesForErrors = false;
var filesWithErrors = {};
provideErrorsToWebpack(filesToCheckForErrors, filesWithErrors, compilation, modules, instance);
provideDeclarationFilesToWebpack(filesToCheckForErrors, instance.languageService, compilation);
instance.filesWithErrors = filesWithErrors;
instance.modifiedFiles = null;
callback();
};
}
/**
* handle compiler option errors after the first compile
*/
function provideCompilerOptionDiagnosticErrorsToWebpack(getCompilerOptionDiagnostics, compilation, instance, configFilePath) {
if (getCompilerOptionDiagnostics) {
var languageService = instance.languageService, loaderOptions = instance.loaderOptions, compiler = instance.compiler;
utils.registerWebpackErrors(compilation.errors, utils.formatErrors(languageService.getCompilerOptionsDiagnostics(), loaderOptions, compiler, { file: configFilePath || 'tsconfig.json' }));
}
}
/**
* build map of all modules based on normalized filename
* this is used for quick-lookup when trying to find modules
* based on filepath
*/
function determineModules(compilation) {
var modules = {};
compilation.modules.forEach(function (module) {
if (module.resource) {
var modulePath = path.normalize(module.resource);
if (utils.hasOwnProperty(modules, modulePath)) {
var existingModules = modules[modulePath];
if (existingModules.indexOf(module) === -1) {
existingModules.push(module);
}
}
else {
modules[modulePath] = [module];
}
}
});
return modules;
}
function determineFilesToCheckForErrors(checkAllFilesForErrors, instance) {
var files = instance.files, modifiedFiles = instance.modifiedFiles, filesWithErrors = instance.filesWithErrors;
// calculate array of files to check
var filesToCheckForErrors = {};
if (checkAllFilesForErrors) {
// check all files on initial run
filesToCheckForErrors = files;
}
else if (modifiedFiles) {
// check all modified files, and all dependants
Object.keys(modifiedFiles).forEach(function (modifiedFileName) {
utils.collectAllDependants(instance.reverseDependencyGraph, modifiedFileName)
.forEach(function (fileName) {
filesToCheckForErrors[fileName] = files[fileName];
});
});
}
// re-check files with errors from previous build
if (filesWithErrors) {
Object.keys(filesWithErrors).forEach(function (fileWithErrorName) {
return filesToCheckForErrors[fileWithErrorName] = filesWithErrors[fileWithErrorName];
});
}
return filesToCheckForErrors;
}
function provideErrorsToWebpack(filesToCheckForErrors, filesWithErrors, compilation, modules, instance) {
var compiler = instance.compiler, languageService = instance.languageService, files = instance.files, loaderOptions = instance.loaderOptions;
Object.keys(filesToCheckForErrors)
.filter(function (filePath) { return !!filePath.match(constants.dtsTsTsxRegex); })
.forEach(function (filePath) {
var errors = languageService.getSyntacticDiagnostics(filePath).concat(languageService.getSemanticDiagnostics(filePath));
if (errors.length > 0) {
filesWithErrors[filePath] = files[filePath];
}
// if we have access to a webpack module, use that
if (utils.hasOwnProperty(modules, filePath)) {
var associatedModules = modules[filePath];
associatedModules.forEach(function (module) {
// remove any existing errors
removeTSLoaderErrors(module.errors);
// append errors
var formattedErrors = utils.formatErrors(errors, loaderOptions, compiler, { module: module });
utils.registerWebpackErrors(module.errors, formattedErrors);
utils.registerWebpackErrors(compilation.errors, formattedErrors);
});
}
else {
// otherwise it's a more generic error
utils.registerWebpackErrors(compilation.errors, utils.formatErrors(errors, loaderOptions, compiler, { file: filePath }));
}
});
}
/**
* gather all declaration files from TypeScript and output them to webpack
*/
function provideDeclarationFilesToWebpack(filesToCheckForErrors, languageService, compilation) {
Object.keys(filesToCheckForErrors)
.filter(function (filePath) { return !!filePath.match(constants.tsTsxRegex); })
.forEach(function (filePath) {
var output = languageService.getEmitOutput(filePath);
var declarationFile = output.outputFiles.filter(function (outputFile) { return !!outputFile.name.match(constants.dtsDtsxRegex); }).pop();
if (declarationFile) {
var assetPath = path.relative(compilation.compiler.context, declarationFile.name);
compilation.assets[assetPath] = {
source: function () { return declarationFile.text; },
size: function () { return declarationFile.text.length; },
};
}
});
}
/**
* handle all other errors. The basic approach here to get accurate error
* reporting is to start with a "blank slate" each compilation and gather
* all errors from all files. Since webpack tracks errors in a module from
* compilation-to-compilation, and since not every module always runs through
* the loader, we need to detect and remove any pre-existing errors.
*/
function removeTSLoaderErrors(errors) {
var index = -1;
var length = errors.length;
while (++index < length) {
if (errors[index].loaderSource === 'ts-loader') {
errors.splice(index--, 1);
length--;
}
}
}
module.exports = makeAfterCompile;