Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed missing errors in watch mode in webpack5 #1208

Merged
merged 2 commits into from
Nov 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## v8.0.10
* [Fixed missing errors in watch mode in webpack5](https://github.com/TypeStrong/ts-loader/issues/1204) - thanks @appzuka

## v8.0.9
* [Fixed build failing when using thread-loader](https://github.com/TypeStrong/ts-loader/pull/1207) - thanks @valerio

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ts-loader",
"version": "8.0.9",
"version": "8.0.10",
"description": "TypeScript loader for webpack",
"main": "index.js",
"types": "dist",
Expand Down
61 changes: 38 additions & 23 deletions src/after-compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,16 @@ import {
tsLoaderSource,
} from './utils';

/**
* This returns a function that has options to add assets and also to provide errors to webpack
* In webpack 4 we can do both during the afterCompile hook
* In webpack 5 only errors should be provided during aftercompile. Assets should be
* emitted during the afterProcessAssets hook
*/
export function makeAfterCompile(
instance: TSInstance,
addAssets: boolean,
provideErrors: boolean,
configFilePath: string | undefined
) {
let getCompilerOptionDiagnostics = true;
Expand All @@ -39,18 +47,22 @@ export function makeAfterCompile(
}

if (instance.loaderOptions.transpileOnly) {
provideAssetsFromSolutionBuilderHost(instance, compilation);
if (addAssets) {
provideAssetsFromSolutionBuilderHost(instance, compilation);
}
callback();
return;
}
removeCompilationTSLoaderErrors(compilation, instance.loaderOptions);

provideCompilerOptionDiagnosticErrorsToWebpack(
getCompilerOptionDiagnostics,
compilation,
instance,
configFilePath
);
if (provideErrors) {
provideCompilerOptionDiagnosticErrorsToWebpack(
getCompilerOptionDiagnostics,
compilation,
instance,
configFilePath
);
}
getCompilerOptionDiagnostics = false;

const modules = determineModules(compilation, instance);
Expand All @@ -62,22 +74,25 @@ export function makeAfterCompile(
checkAllFilesForErrors = false;

const filesWithErrors: TSFiles = new Map();
provideErrorsToWebpack(
filesToCheckForErrors,
filesWithErrors,
compilation,
modules,
instance
);
provideDeclarationFilesToWebpack(
filesToCheckForErrors,
instance,
compilation
);
provideTsBuildInfoFilesToWebpack(instance, compilation);

provideSolutionErrorsToWebpack(compilation, modules, instance);
provideAssetsFromSolutionBuilderHost(instance, compilation);
if (provideErrors) {
provideErrorsToWebpack(
filesToCheckForErrors,
filesWithErrors,
compilation,
modules,
instance
);
provideSolutionErrorsToWebpack(compilation, modules, instance);
}
if (addAssets) {
provideDeclarationFilesToWebpack(
filesToCheckForErrors,
instance,
compilation
);
provideTsBuildInfoFilesToWebpack(instance, compilation);
provideAssetsFromSolutionBuilderHost(instance, compilation);
}

instance.filesWithErrors = filesWithErrors;
instance.modifiedFiles = undefined;
Expand Down
83 changes: 43 additions & 40 deletions src/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,46 @@ function getExistingSolutionBuilderHost(key: FilePathKey) {
return undefined;
}

// Adding assets in afterCompile is deprecated in webpack 5 so we
// need different behavior for webpack4 and 5
const addAssetHooks = !!webpack.version!.match(/^4.*/)
? (loader: webpack.loader.LoaderContext, instance: TSInstance) => {
// add makeAfterCompile with addAssets = true to emit assets and report errors
loader._compiler.hooks.afterCompile.tapAsync(
'ts-loader',
makeAfterCompile(instance, true, true, instance.configFilePath)
);
}
: (loader: webpack.loader.LoaderContext, instance: TSInstance) => {
// We must be running under webpack 5+

// Add makeAfterCompile with addAssets = false to suppress emitting assets
// during the afterCompile stage. Errors will be still be reported to webpack
loader._compiler.hooks.afterCompile.tapAsync(
'ts-loader',
makeAfterCompile(instance, false, true, instance.configFilePath)
);

// Emit the assets at the afterProcessAssets stage
loader._compilation.hooks.afterProcessAssets.tap(
'ts-loader',
(_: any) => {
makeAfterCompile(
instance,
true,
false,
instance.configFilePath
)(loader._compilation, () => {
return null;
});
}
);

// It may be better to add assets at the processAssets stage (https://webpack.js.org/api/compilation-hooks/#processassets)
// This requires Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL, which does not exist in webpack4
// Consider changing this when ts-loader is built using webpack5
};

export function initializeInstance(
loader: webpack.loader.LoaderContext,
instance: TSInstance
Expand Down Expand Up @@ -350,26 +390,7 @@ export function initializeInstance(
instance.transformers = getCustomTransformers(program);
// Setup watch run for solution building
if (instance.solutionBuilderHost) {
if (loader._compilation.hooks.afterProcessAssets) {
// afterProcessAssets does not exist in webpack4
loader._compilation.hooks.afterProcessAssets.tap(
'ts-loader',
(_: any) => {
makeAfterCompile(instance, instance.configFilePath)(
loader._compilation,
() => {
return null;
}
);
}
);
} else {
// adding assets in afterCompile is deprecated in webpack 5
loader._compiler.hooks.afterCompile.tapAsync(
'ts-loader',
makeAfterCompile(instance, instance.configFilePath)
);
}
addAssetHooks(loader, instance);
loader._compiler.hooks.watchRun.tapAsync(
'ts-loader',
makeWatchRun(instance, loader)
Expand Down Expand Up @@ -416,26 +437,8 @@ export function initializeInstance(
instance.languageService!.getProgram()
);
}
if (loader._compilation.hooks.afterProcessAssets) {
// afterProcessAssets does not exist in webpack4
loader._compilation.hooks.afterProcessAssets.tap(
'ts-loader',
(_: any) => {
makeAfterCompile(instance, instance.configFilePath)(
loader._compilation,
() => {
return null;
}
);
}
);
} else {
// adding assets in afterCompile is deprecated in webpack 5
loader._compiler.hooks.afterCompile.tapAsync(
'ts-loader',
makeAfterCompile(instance, instance.configFilePath)
);
}

addAssetHooks(loader, instance);

loader._compiler.hooks.watchRun.tapAsync(
'ts-loader',
Expand Down