Skip to content

Commit 391d60c

Browse files
clydinalan-agius4
authored andcommitted
fix(@ngtools/webpack): remove use of Webpack compilation fileTimestamps property
The `fileTimestamps` property on the Webpack compilation object no longer exists with Webpack 5. This change uses the Webpack compiler's property of the same name instead. The cache invalidation is also moved to a separate file and now calculates the changed file set as well. This eliminates the second iteration of the file timestamps within the resource loader.
1 parent c21742b commit 391d60c

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import * as ts from 'typescript';
9+
import { normalizePath } from './paths';
10+
11+
export class SourceFileCache extends Map<string, ts.SourceFile> {
12+
invalidate(
13+
fileTimestamps: Map<string, number | { timestamp: number } | null>,
14+
buildTimestamp: number,
15+
): Set<string> {
16+
const changedFiles = new Set<string>();
17+
for (const [file, timeOrEntry] of fileTimestamps) {
18+
const time =
19+
timeOrEntry && (typeof timeOrEntry === 'number' ? timeOrEntry : timeOrEntry.timestamp);
20+
if (time === null || buildTimestamp < time) {
21+
// Cache stores paths using the POSIX directory separator
22+
const normalizedFile = normalizePath(file);
23+
this.delete(normalizedFile);
24+
changedFiles.add(normalizedFile);
25+
}
26+
}
27+
28+
return changedFiles;
29+
}
30+
}

packages/ngtools/webpack/src/ivy/plugin.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { TypeScriptPathsPlugin } from '../paths-plugin';
2020
import { WebpackResourceLoader } from '../resource_loader';
2121
import { addError, addWarning } from '../webpack-diagnostics';
2222
import { isWebpackFiveOrHigher, mergeResolverMainFields } from '../webpack-version';
23+
import { SourceFileCache } from './cache';
2324
import { DiagnosticsReporter, createDiagnosticsReporter } from './diagnostics';
2425
import {
2526
augmentHostWithCaching,
@@ -81,7 +82,7 @@ export class AngularWebpackPlugin {
8182
private watchMode?: boolean;
8283
private ngtscNextProgram?: NgtscProgram;
8384
private builder?: ts.EmitAndSemanticDiagnosticsBuilderProgram;
84-
private sourceFileCache?: Map<string, ts.SourceFile>;
85+
private sourceFileCache?: SourceFileCache;
8586
private buildTimestamp!: number;
8687
private readonly lazyRouteMap: Record<string, string> = {};
8788
private readonly requiredFilesToEmit = new Set<string>();
@@ -186,17 +187,13 @@ export class AngularWebpackPlugin {
186187

187188
// Setup source file caching and reuse cache from previous compilation if present
188189
let cache = this.sourceFileCache;
190+
let changedFiles;
189191
if (cache) {
190-
// Invalidate existing cache based on compilation file timestamps
191-
for (const [file, time] of compilation.fileTimestamps) {
192-
if (this.buildTimestamp < time) {
193-
// Cache stores paths using the POSIX directory separator
194-
cache.delete(normalizePath(file));
195-
}
196-
}
192+
// Invalidate existing cache based on compiler file timestamps
193+
changedFiles = cache.invalidate(compiler.fileTimestamps, this.buildTimestamp);
197194
} else {
198195
// Initialize a new cache
199-
cache = new Map();
196+
cache = new SourceFileCache();
200197
// Only store cache if in watch mode
201198
if (this.watchMode) {
202199
this.sourceFileCache = cache;
@@ -215,7 +212,7 @@ export class AngularWebpackPlugin {
215212
augmentHostWithNgcc(host, ngccProcessor, moduleResolutionCache);
216213

217214
// Setup resource loading
218-
resourceLoader.update(compilation);
215+
resourceLoader.update(compilation, changedFiles);
219216
augmentHostWithResources(host, resourceLoader, {
220217
directTemplateLoading: this.pluginOptions.directTemplateLoading,
221218
});

packages/ngtools/webpack/src/resource_loader.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,22 @@ export class WebpackResourceLoader {
3232
private _cachedSources = new Map<string, string>();
3333
private _cachedEvaluatedSources = new Map<string, RawSource>();
3434

35-
private buildTimestamp?: number;
36-
public changedFiles = new Set<string>();
35+
public changedFiles?: Iterable<string>;
3736

38-
update(parentCompilation: import('webpack').compilation.Compilation) {
37+
update(parentCompilation: import('webpack').compilation.Compilation, changedFiles?: Iterable<string>) {
3938
this._parentCompilation = parentCompilation;
4039
this._context = parentCompilation.context;
4140

4241
// Update changed file list
43-
if (this.buildTimestamp !== undefined) {
44-
this.changedFiles.clear();
45-
for (const [file, time] of parentCompilation.fileTimestamps) {
46-
if (this.buildTimestamp < time) {
47-
this.changedFiles.add(normalizePath(file));
48-
}
49-
}
50-
}
51-
this.buildTimestamp = Date.now();
42+
this.changedFiles = changedFiles;
5243
}
5344

5445
getModifiedResourceFiles() {
5546
const modifiedResources = new Set<string>();
47+
if (!this.changedFiles) {
48+
return modifiedResources;
49+
}
50+
5651
for (const changedFile of this.changedFiles) {
5752
this.getAffectedResources(
5853
changedFile,

0 commit comments

Comments
 (0)