Skip to content

Commit 4909d99

Browse files
authored
Fixed missing errors in watch mode in webpack5 (#1208)
* Fixed missing errors in watch mode in webpack5 * Refactor to use regex only once
1 parent 3f73e98 commit 4909d99

File tree

4 files changed

+85
-64
lines changed

4 files changed

+85
-64
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## v8.0.10
4+
* [Fixed missing errors in watch mode in webpack5](https://github.com/TypeStrong/ts-loader/issues/1204) - thanks @appzuka
5+
36
## v8.0.9
47
* [Fixed build failing when using thread-loader](https://github.com/TypeStrong/ts-loader/pull/1207) - thanks @valerio
58

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ts-loader",
3-
"version": "8.0.9",
3+
"version": "8.0.10",
44
"description": "TypeScript loader for webpack",
55
"main": "index.js",
66
"types": "dist",

src/after-compile.ts

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@ import {
2121
tsLoaderSource,
2222
} from './utils';
2323

24+
/**
25+
* This returns a function that has options to add assets and also to provide errors to webpack
26+
* In webpack 4 we can do both during the afterCompile hook
27+
* In webpack 5 only errors should be provided during aftercompile. Assets should be
28+
* emitted during the afterProcessAssets hook
29+
*/
2430
export function makeAfterCompile(
2531
instance: TSInstance,
32+
addAssets: boolean,
33+
provideErrors: boolean,
2634
configFilePath: string | undefined
2735
) {
2836
let getCompilerOptionDiagnostics = true;
@@ -39,18 +47,22 @@ export function makeAfterCompile(
3947
}
4048

4149
if (instance.loaderOptions.transpileOnly) {
42-
provideAssetsFromSolutionBuilderHost(instance, compilation);
50+
if (addAssets) {
51+
provideAssetsFromSolutionBuilderHost(instance, compilation);
52+
}
4353
callback();
4454
return;
4555
}
4656
removeCompilationTSLoaderErrors(compilation, instance.loaderOptions);
4757

48-
provideCompilerOptionDiagnosticErrorsToWebpack(
49-
getCompilerOptionDiagnostics,
50-
compilation,
51-
instance,
52-
configFilePath
53-
);
58+
if (provideErrors) {
59+
provideCompilerOptionDiagnosticErrorsToWebpack(
60+
getCompilerOptionDiagnostics,
61+
compilation,
62+
instance,
63+
configFilePath
64+
);
65+
}
5466
getCompilerOptionDiagnostics = false;
5567

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

6476
const filesWithErrors: TSFiles = new Map();
65-
provideErrorsToWebpack(
66-
filesToCheckForErrors,
67-
filesWithErrors,
68-
compilation,
69-
modules,
70-
instance
71-
);
72-
provideDeclarationFilesToWebpack(
73-
filesToCheckForErrors,
74-
instance,
75-
compilation
76-
);
77-
provideTsBuildInfoFilesToWebpack(instance, compilation);
78-
79-
provideSolutionErrorsToWebpack(compilation, modules, instance);
80-
provideAssetsFromSolutionBuilderHost(instance, compilation);
77+
if (provideErrors) {
78+
provideErrorsToWebpack(
79+
filesToCheckForErrors,
80+
filesWithErrors,
81+
compilation,
82+
modules,
83+
instance
84+
);
85+
provideSolutionErrorsToWebpack(compilation, modules, instance);
86+
}
87+
if (addAssets) {
88+
provideDeclarationFilesToWebpack(
89+
filesToCheckForErrors,
90+
instance,
91+
compilation
92+
);
93+
provideTsBuildInfoFilesToWebpack(instance, compilation);
94+
provideAssetsFromSolutionBuilderHost(instance, compilation);
95+
}
8196

8297
instance.filesWithErrors = filesWithErrors;
8398
instance.modifiedFiles = undefined;

src/instances.ts

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,46 @@ function getExistingSolutionBuilderHost(key: FilePathKey) {
302302
return undefined;
303303
}
304304

305+
// Adding assets in afterCompile is deprecated in webpack 5 so we
306+
// need different behavior for webpack4 and 5
307+
const addAssetHooks = !!webpack.version!.match(/^4.*/)
308+
? (loader: webpack.loader.LoaderContext, instance: TSInstance) => {
309+
// add makeAfterCompile with addAssets = true to emit assets and report errors
310+
loader._compiler.hooks.afterCompile.tapAsync(
311+
'ts-loader',
312+
makeAfterCompile(instance, true, true, instance.configFilePath)
313+
);
314+
}
315+
: (loader: webpack.loader.LoaderContext, instance: TSInstance) => {
316+
// We must be running under webpack 5+
317+
318+
// Add makeAfterCompile with addAssets = false to suppress emitting assets
319+
// during the afterCompile stage. Errors will be still be reported to webpack
320+
loader._compiler.hooks.afterCompile.tapAsync(
321+
'ts-loader',
322+
makeAfterCompile(instance, false, true, instance.configFilePath)
323+
);
324+
325+
// Emit the assets at the afterProcessAssets stage
326+
loader._compilation.hooks.afterProcessAssets.tap(
327+
'ts-loader',
328+
(_: any) => {
329+
makeAfterCompile(
330+
instance,
331+
true,
332+
false,
333+
instance.configFilePath
334+
)(loader._compilation, () => {
335+
return null;
336+
});
337+
}
338+
);
339+
340+
// It may be better to add assets at the processAssets stage (https://webpack.js.org/api/compilation-hooks/#processassets)
341+
// This requires Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL, which does not exist in webpack4
342+
// Consider changing this when ts-loader is built using webpack5
343+
};
344+
305345
export function initializeInstance(
306346
loader: webpack.loader.LoaderContext,
307347
instance: TSInstance
@@ -350,26 +390,7 @@ export function initializeInstance(
350390
instance.transformers = getCustomTransformers(program);
351391
// Setup watch run for solution building
352392
if (instance.solutionBuilderHost) {
353-
if (loader._compilation.hooks.afterProcessAssets) {
354-
// afterProcessAssets does not exist in webpack4
355-
loader._compilation.hooks.afterProcessAssets.tap(
356-
'ts-loader',
357-
(_: any) => {
358-
makeAfterCompile(instance, instance.configFilePath)(
359-
loader._compilation,
360-
() => {
361-
return null;
362-
}
363-
);
364-
}
365-
);
366-
} else {
367-
// adding assets in afterCompile is deprecated in webpack 5
368-
loader._compiler.hooks.afterCompile.tapAsync(
369-
'ts-loader',
370-
makeAfterCompile(instance, instance.configFilePath)
371-
);
372-
}
393+
addAssetHooks(loader, instance);
373394
loader._compiler.hooks.watchRun.tapAsync(
374395
'ts-loader',
375396
makeWatchRun(instance, loader)
@@ -416,26 +437,8 @@ export function initializeInstance(
416437
instance.languageService!.getProgram()
417438
);
418439
}
419-
if (loader._compilation.hooks.afterProcessAssets) {
420-
// afterProcessAssets does not exist in webpack4
421-
loader._compilation.hooks.afterProcessAssets.tap(
422-
'ts-loader',
423-
(_: any) => {
424-
makeAfterCompile(instance, instance.configFilePath)(
425-
loader._compilation,
426-
() => {
427-
return null;
428-
}
429-
);
430-
}
431-
);
432-
} else {
433-
// adding assets in afterCompile is deprecated in webpack 5
434-
loader._compiler.hooks.afterCompile.tapAsync(
435-
'ts-loader',
436-
makeAfterCompile(instance, instance.configFilePath)
437-
);
438-
}
440+
441+
addAssetHooks(loader, instance);
439442

440443
loader._compiler.hooks.watchRun.tapAsync(
441444
'ts-loader',

0 commit comments

Comments
 (0)