Skip to content

Commit b9ee21e

Browse files
committed
refactor(@ngtools/webpack): support function-based host file replacement
1 parent ffa2636 commit b9ee21e

File tree

2 files changed

+43
-20
lines changed

2 files changed

+43
-20
lines changed

packages/ngtools/webpack/src/angular_compiler_plugin.ts

+27-13
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 { Path, dirname, normalize, resolve, virtualFs } from '@angular-devkit/core';
8+
import { Path, dirname, getSystemPath, 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';
@@ -77,7 +77,7 @@ export interface AngularCompilerPluginOptions {
7777
entryModule?: string;
7878
mainPath?: string;
7979
skipCodeGeneration?: boolean;
80-
hostReplacementPaths?: { [path: string]: string };
80+
hostReplacementPaths?: { [path: string]: string } | ((path: string) => string);
8181
forkTypeChecker?: boolean;
8282
// TODO: remove singleFileIncludes for 2.0, this is just to support old projects that did not
8383
// include 'polyfills.ts' in `tsconfig.spec.json'.
@@ -292,11 +292,20 @@ export class AngularCompilerPlugin {
292292

293293
let host: virtualFs.Host<fs.Stats> = options.host || new NodeJsSyncHost();
294294
if (options.hostReplacementPaths) {
295-
const aliasHost = new virtualFs.AliasHost(host);
296-
for (const from in options.hostReplacementPaths) {
297-
aliasHost.aliases.set(normalize(from), normalize(options.hostReplacementPaths[from]));
295+
if (typeof options.hostReplacementPaths == 'function') {
296+
const replacementResolver = options.hostReplacementPaths;
297+
host = new class extends virtualFs.ResolverHost<fs.Stats> {
298+
_resolve(path: Path) {
299+
return normalize(replacementResolver(getSystemPath(path)));
300+
}
301+
}(host);
302+
} else {
303+
const aliasHost = new virtualFs.AliasHost(host);
304+
for (const from in options.hostReplacementPaths) {
305+
aliasHost.aliases.set(normalize(from), normalize(options.hostReplacementPaths[from]));
306+
}
307+
host = aliasHost;
298308
}
299-
host = aliasHost;
300309
}
301310

302311
// Create the webpack compiler host.
@@ -618,14 +627,19 @@ export class AngularCompilerPlugin {
618627
);
619628
compilerWithFileSystems.inputFileSystem = inputDecorator;
620629

621-
let replacements: Map<Path, Path> | undefined;
630+
let replacements: Map<Path, Path> | ((path: Path) => Path) | undefined;
622631
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-
);
632+
if (typeof this._options.hostReplacementPaths === 'function') {
633+
const replacementResolver = this._options.hostReplacementPaths;
634+
replacements = path => normalize(replacementResolver(getSystemPath(path)));
635+
} else {
636+
replacements = new Map();
637+
for (const replace in this._options.hostReplacementPaths) {
638+
replacements.set(
639+
normalize(replace),
640+
normalize(this._options.hostReplacementPaths[replace]),
641+
);
642+
}
629643
}
630644
}
631645

packages/ngtools/webpack/src/virtual_file_system_decorator.ts

+16-7
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export class VirtualFileSystemDecorator implements InputFileSystem {
108108
export class VirtualWatchFileSystemDecorator extends NodeWatchFileSystem {
109109
constructor(
110110
private _virtualInputFileSystem: VirtualFileSystemDecorator,
111-
private _replacements?: Map<Path, Path>,
111+
private _replacements?: Map<Path, Path> | ((path: Path) => Path),
112112
) {
113113
super(_virtualInputFileSystem);
114114
}
@@ -177,14 +177,23 @@ export class VirtualWatchFileSystemDecorator extends NodeWatchFileSystem {
177177
const replacements = this._replacements;
178178

179179
return original.map(file => {
180-
const replacement = replacements.get(normalize(file));
181-
if (replacement) {
182-
const fullReplacement = getSystemPath(replacement);
183-
reverseReplacements.set(fullReplacement, file);
180+
if (typeof replacements === 'function') {
181+
const replacement = getSystemPath(replacements(normalize(file)));
182+
if (replacement !== file) {
183+
reverseReplacements.set(replacement, file);
184+
}
184185

185-
return fullReplacement;
186+
return replacement;
186187
} else {
187-
return file;
188+
const replacement = replacements.get(normalize(file));
189+
if (replacement) {
190+
const fullReplacement = getSystemPath(replacement);
191+
reverseReplacements.set(fullReplacement, file);
192+
193+
return fullReplacement;
194+
} else {
195+
return file;
196+
}
188197
}
189198
});
190199
};

0 commit comments

Comments
 (0)