Skip to content

Commit

Permalink
fix(@ngtools/webpack): remove use of Webpack compilation fileTimestam…
Browse files Browse the repository at this point in the history
…ps 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.
  • Loading branch information
clydin authored and alan-agius4 committed Nov 30, 2020
1 parent c21742b commit 391d60c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 22 deletions.
30 changes: 30 additions & 0 deletions packages/ngtools/webpack/src/ivy/cache.ts
@@ -0,0 +1,30 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import { normalizePath } from './paths';

export class SourceFileCache extends Map<string, ts.SourceFile> {
invalidate(
fileTimestamps: Map<string, number | { timestamp: number } | null>,
buildTimestamp: number,
): Set<string> {
const changedFiles = new Set<string>();
for (const [file, timeOrEntry] of fileTimestamps) {
const time =
timeOrEntry && (typeof timeOrEntry === 'number' ? timeOrEntry : timeOrEntry.timestamp);
if (time === null || buildTimestamp < time) {
// Cache stores paths using the POSIX directory separator
const normalizedFile = normalizePath(file);
this.delete(normalizedFile);
changedFiles.add(normalizedFile);
}
}

return changedFiles;
}
}
17 changes: 7 additions & 10 deletions packages/ngtools/webpack/src/ivy/plugin.ts
Expand Up @@ -20,6 +20,7 @@ import { TypeScriptPathsPlugin } from '../paths-plugin';
import { WebpackResourceLoader } from '../resource_loader';
import { addError, addWarning } from '../webpack-diagnostics';
import { isWebpackFiveOrHigher, mergeResolverMainFields } from '../webpack-version';
import { SourceFileCache } from './cache';
import { DiagnosticsReporter, createDiagnosticsReporter } from './diagnostics';
import {
augmentHostWithCaching,
Expand Down Expand Up @@ -81,7 +82,7 @@ export class AngularWebpackPlugin {
private watchMode?: boolean;
private ngtscNextProgram?: NgtscProgram;
private builder?: ts.EmitAndSemanticDiagnosticsBuilderProgram;
private sourceFileCache?: Map<string, ts.SourceFile>;
private sourceFileCache?: SourceFileCache;
private buildTimestamp!: number;
private readonly lazyRouteMap: Record<string, string> = {};
private readonly requiredFilesToEmit = new Set<string>();
Expand Down Expand Up @@ -186,17 +187,13 @@ export class AngularWebpackPlugin {

// Setup source file caching and reuse cache from previous compilation if present
let cache = this.sourceFileCache;
let changedFiles;
if (cache) {
// Invalidate existing cache based on compilation file timestamps
for (const [file, time] of compilation.fileTimestamps) {
if (this.buildTimestamp < time) {
// Cache stores paths using the POSIX directory separator
cache.delete(normalizePath(file));
}
}
// Invalidate existing cache based on compiler file timestamps
changedFiles = cache.invalidate(compiler.fileTimestamps, this.buildTimestamp);
} else {
// Initialize a new cache
cache = new Map();
cache = new SourceFileCache();
// Only store cache if in watch mode
if (this.watchMode) {
this.sourceFileCache = cache;
Expand All @@ -215,7 +212,7 @@ export class AngularWebpackPlugin {
augmentHostWithNgcc(host, ngccProcessor, moduleResolutionCache);

// Setup resource loading
resourceLoader.update(compilation);
resourceLoader.update(compilation, changedFiles);
augmentHostWithResources(host, resourceLoader, {
directTemplateLoading: this.pluginOptions.directTemplateLoading,
});
Expand Down
19 changes: 7 additions & 12 deletions packages/ngtools/webpack/src/resource_loader.ts
Expand Up @@ -32,27 +32,22 @@ export class WebpackResourceLoader {
private _cachedSources = new Map<string, string>();
private _cachedEvaluatedSources = new Map<string, RawSource>();

private buildTimestamp?: number;
public changedFiles = new Set<string>();
public changedFiles?: Iterable<string>;

update(parentCompilation: import('webpack').compilation.Compilation) {
update(parentCompilation: import('webpack').compilation.Compilation, changedFiles?: Iterable<string>) {
this._parentCompilation = parentCompilation;
this._context = parentCompilation.context;

// Update changed file list
if (this.buildTimestamp !== undefined) {
this.changedFiles.clear();
for (const [file, time] of parentCompilation.fileTimestamps) {
if (this.buildTimestamp < time) {
this.changedFiles.add(normalizePath(file));
}
}
}
this.buildTimestamp = Date.now();
this.changedFiles = changedFiles;
}

getModifiedResourceFiles() {
const modifiedResources = new Set<string>();
if (!this.changedFiles) {
return modifiedResources;
}

for (const changedFile of this.changedFiles) {
this.getAffectedResources(
changedFile,
Expand Down

0 comments on commit 391d60c

Please sign in to comment.