Skip to content

Commit 86a62ad

Browse files
committed
fix(@ngtools/webpack): support watching file replacements
1 parent e31af46 commit 86a62ad

File tree

2 files changed

+98
-18
lines changed

2 files changed

+98
-18
lines changed

packages/ngtools/webpack/src/angular_compiler_plugin.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import { dirname, normalize, resolve, virtualFs } from '@angular-devkit/core';
8+
import { Path, dirname, normalize, resolve, virtualFs } from '@angular-devkit/core';
99
import { NodeJsSyncHost } from '@angular-devkit/core/node';
1010
import { ChildProcess, ForkOptions, fork } from 'child_process';
1111
import * as fs from 'fs';
@@ -617,8 +617,21 @@ export class AngularCompilerPlugin {
617617
this._compilerHost,
618618
);
619619
compilerWithFileSystems.inputFileSystem = inputDecorator;
620+
621+
let replacements: Map<Path, Path> | undefined;
622+
if (this._options.hostReplacementPaths) {
623+
replacements = new Map();
624+
for (const replace in this._options.hostReplacementPaths) {
625+
replacements.set(
626+
normalize(replace),
627+
normalize(this._options.hostReplacementPaths[replace]),
628+
);
629+
}
630+
}
631+
620632
compilerWithFileSystems.watchFileSystem = new VirtualWatchFileSystemDecorator(
621633
inputDecorator,
634+
replacements,
622635
);
623636
});
624637

packages/ngtools/webpack/src/virtual_file_system_decorator.ts

+84-17
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8+
import { Path, getSystemPath, normalize } from '@angular-devkit/core';
89
import { Stats } from 'fs';
910
import { WebpackCompilerHost } from './compiler_host';
1011
import { Callback, InputFileSystem, NodeWatchFileSystemInterface } from './webpack';
@@ -105,38 +106,104 @@ export class VirtualFileSystemDecorator implements InputFileSystem {
105106
}
106107

107108
export class VirtualWatchFileSystemDecorator extends NodeWatchFileSystem {
108-
constructor(private _virtualInputFileSystem: VirtualFileSystemDecorator) {
109+
constructor(
110+
private _virtualInputFileSystem: VirtualFileSystemDecorator,
111+
private _replacements?: Map<Path, Path>,
112+
) {
109113
super(_virtualInputFileSystem);
110114
}
111115

112116
watch(
113-
files: any, // tslint:disable-line:no-any
114-
dirs: any, // tslint:disable-line:no-any
115-
missing: any, // tslint:disable-line:no-any
116-
startTime: any, // tslint:disable-line:no-any
117-
options: any, // tslint:disable-line:no-any
117+
files: string[],
118+
dirs: string[],
119+
missing: string[],
120+
startTime: number | undefined,
121+
options: {},
118122
callback: any, // tslint:disable-line:no-any
119-
callbackUndelayed: any, // tslint:disable-line:no-any
123+
callbackUndelayed: (filename: string, timestamp: number) => void,
120124
) {
125+
const reverseReplacements = new Map<string, string>();
126+
const reverseTimestamps = (map: Map<string, number>) => {
127+
for (const entry of Array.from(map.entries())) {
128+
const original = reverseReplacements.get(entry[0]);
129+
if (original) {
130+
map.set(original, entry[1]);
131+
map.delete(entry[0]);
132+
}
133+
}
134+
135+
return map;
136+
};
137+
138+
const newCallbackUndelayed = (filename: string, timestamp: number) => {
139+
const original = reverseReplacements.get(filename);
140+
if (original) {
141+
this._virtualInputFileSystem.purge(original);
142+
callbackUndelayed(original, timestamp);
143+
} else {
144+
callbackUndelayed(filename, timestamp);
145+
}
146+
};
147+
121148
const newCallback = (
122-
err: any, // tslint:disable-line:no-any
123-
filesModified: any, // tslint:disable-line:no-any
124-
contextModified: any, // tslint:disable-line:no-any
125-
missingModified: any, // tslint:disable-line:no-any
126-
fileTimestamps: { [k: string]: number },
127-
contextTimestamps: { [k: string]: number },
149+
err: Error | null,
150+
filesModified: string[],
151+
contextModified: string[],
152+
missingModified: string[],
153+
fileTimestamps: Map<string, number>,
154+
contextTimestamps: Map<string, number>,
128155
) => {
129156
// Update fileTimestamps with timestamps from virtual files.
130157
const virtualFilesStats = this._virtualInputFileSystem.getVirtualFilesPaths()
131158
.map((fileName) => ({
132159
path: fileName,
133160
mtime: +this._virtualInputFileSystem.statSync(fileName).mtime,
134161
}));
135-
virtualFilesStats.forEach(stats => fileTimestamps[stats.path] = +stats.mtime);
136-
callback(err, filesModified, contextModified, missingModified, fileTimestamps,
137-
contextTimestamps);
162+
virtualFilesStats.forEach(stats => fileTimestamps.set(stats.path, +stats.mtime));
163+
callback(
164+
err,
165+
filesModified.map(value => reverseReplacements.get(value) || value),
166+
contextModified.map(value => reverseReplacements.get(value) || value),
167+
missingModified.map(value => reverseReplacements.get(value) || value),
168+
reverseTimestamps(fileTimestamps),
169+
reverseTimestamps(contextTimestamps),
170+
);
171+
};
172+
173+
const mapReplacements = (original: string[]): string[] => {
174+
if (!this._replacements) {
175+
return original;
176+
}
177+
const replacements = this._replacements;
178+
179+
return original.map(file => {
180+
const replacement = replacements.get(normalize(file));
181+
if (replacement) {
182+
const fullReplacement = getSystemPath(replacement);
183+
reverseReplacements.set(fullReplacement, file);
184+
185+
return fullReplacement;
186+
} else {
187+
return file;
188+
}
189+
});
138190
};
139191

140-
return super.watch(files, dirs, missing, startTime, options, newCallback, callbackUndelayed);
192+
const watcher = super.watch(
193+
mapReplacements(files),
194+
mapReplacements(dirs),
195+
mapReplacements(missing),
196+
startTime,
197+
options,
198+
newCallback,
199+
newCallbackUndelayed,
200+
);
201+
202+
return {
203+
close: () => watcher.close(),
204+
pause: () => watcher.pause(),
205+
getFileTimestamps: () => reverseTimestamps(watcher.getFileTimestamps()),
206+
getContextTimestamps: () => reverseTimestamps(watcher.getContextTimestamps()),
207+
};
141208
}
142209
}

0 commit comments

Comments
 (0)