Skip to content

Commit a2bab51

Browse files
committed
refactor(@angular-devkit/build-angular): use plugin for file replacement
1 parent 0172345 commit a2bab51

File tree

7 files changed

+88
-52
lines changed

7 files changed

+88
-52
lines changed

packages/angular_devkit/build_angular/src/angular-cli-files/models/build-options.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010

1111
// tslint:disable-next-line:no-implicit-dependencies
1212
import * as ts from 'typescript';
13-
import { AssetPatternObject, Budget, ExtraEntryPoint } from '../../browser/schema';
13+
import {
14+
AssetPatternObject,
15+
Budget,
16+
CurrentFileReplacement,
17+
ExtraEntryPoint,
18+
} from '../../browser/schema';
1419

1520
export interface BuildOptions {
1621
optimization: boolean;
@@ -58,6 +63,7 @@ export interface BuildOptions {
5863
stylePreprocessorOptions?: { includePaths: string[] };
5964
lazyModules: string[];
6065
platform?: 'browser' | 'server';
66+
fileReplacements: CurrentFileReplacement[];
6167
}
6268

6369
export interface WebpackTestOptions extends BuildOptions {

packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/typescript.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88
// tslint:disable
99
// TODO: cleanup this file, it's copied as is from Angular CLI.
10-
import { tags, virtualFs } from '@angular-devkit/core';
10+
import { virtualFs } from '@angular-devkit/core';
1111
import { Stats } from 'fs';
1212
import * as path from 'path';
1313
import {
@@ -62,6 +62,13 @@ function _createAotPlugin(
6262
}
6363
}
6464

65+
const hostReplacementPaths: { [replace: string]: string } = {};
66+
if (buildOptions.fileReplacements) {
67+
for (const replacement of buildOptions.fileReplacements) {
68+
hostReplacementPaths[replacement.replace] = replacement.with;
69+
}
70+
}
71+
6572
const pluginOptions: AngularCompilerPluginOptions = {
6673
mainPath: useMain ? path.join(root, buildOptions.main) : undefined,
6774
...i18nFileAndFormat,
@@ -70,6 +77,7 @@ function _createAotPlugin(
7077
missingTranslation: buildOptions.i18nMissingTranslation,
7178
sourceMap: buildOptions.sourceMap,
7279
additionalLazyModules,
80+
hostReplacementPaths,
7381
nameLazyFiles: buildOptions.namedChunks,
7482
forkTypeChecker: buildOptions.forkTypeChecker,
7583
contextElementDependencyConstructor: require('webpack/lib/dependencies/ContextElementDependency'),

packages/angular_devkit/build_angular/src/browser/index.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
statsToString,
3535
statsWarningsToString,
3636
} from '../angular-cli-files/utilities/stats';
37-
import { addFileReplacements, normalizeAssetPatterns } from '../utils';
37+
import { normalizeAssetPatterns, normalizeFileReplacements } from '../utils';
3838
import { AssetPatternObject, BrowserBuilderSchema, CurrentFileReplacement } from './schema';
3939
const webpackMerge = require('webpack-merge');
4040

@@ -64,7 +64,8 @@ export class BrowserBuilder implements Builder<BrowserBuilderSchema> {
6464
concatMap(() => options.deleteOutputPath
6565
? this._deleteOutputDir(root, normalize(options.outputPath), this.context.host)
6666
: of(null)),
67-
concatMap(() => addFileReplacements(root, host, options.fileReplacements)),
67+
concatMap(() => normalizeFileReplacements(options.fileReplacements, host, root)),
68+
tap(fileReplacements => options.fileReplacements = fileReplacements),
6869
concatMap(() => normalizeAssetPatterns(
6970
options.assets, host, root, projectRoot, builderConfig.sourceRoot)),
7071
// Replace the assets in options with the normalized version.

packages/angular_devkit/build_angular/src/dev-server/index.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import * as WebpackDevServer from 'webpack-dev-server';
2525
import { checkPort } from '../angular-cli-files/utilities/check-port';
2626
import { BrowserBuilder, NormalizedBrowserBuilderSchema, getBrowserLoggingCb } from '../browser/';
2727
import { BrowserBuilderSchema } from '../browser/schema';
28-
import { addFileReplacements, normalizeAssetPatterns } from '../utils';
28+
import { normalizeAssetPatterns, normalizeFileReplacements } from '../utils';
2929
const opn = require('opn');
3030

3131

@@ -78,7 +78,8 @@ export class DevServerBuilder implements Builder<DevServerBuilderOptions> {
7878
tap((port) => options.port = port),
7979
concatMap(() => this._getBrowserOptions(options)),
8080
tap((opts) => browserOptions = opts),
81-
concatMap(() => addFileReplacements(root, host, browserOptions.fileReplacements)),
81+
concatMap(() => normalizeFileReplacements(browserOptions.fileReplacements, host, root)),
82+
tap(fileReplacements => browserOptions.fileReplacements = fileReplacements),
8283
concatMap(() => normalizeAssetPatterns(
8384
browserOptions.assets, host, root, projectRoot, builderConfig.sourceRoot)),
8485
// Replace the assets in options with the normalized version.

packages/angular_devkit/build_angular/src/karma/index.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig';
2828
import { requireProjectModule } from '../angular-cli-files/utilities/require-project-module';
2929
import { AssetPatternObject, CurrentFileReplacement } from '../browser/schema';
30-
import { addFileReplacements, normalizeAssetPatterns } from '../utils';
30+
import { normalizeAssetPatterns, normalizeFileReplacements } from '../utils';
3131
import { KarmaBuilderSchema } from './schema';
3232
const webpackMerge = require('webpack-merge');
3333

@@ -47,7 +47,8 @@ export class KarmaBuilder implements Builder<KarmaBuilderSchema> {
4747
const host = new virtualFs.AliasHost(this.context.host as virtualFs.Host<fs.Stats>);
4848

4949
return of(null).pipe(
50-
concatMap(() => addFileReplacements(root, host, options.fileReplacements)),
50+
concatMap(() => normalizeFileReplacements(options.fileReplacements, host, root)),
51+
tap(fileReplacements => options.fileReplacements = fileReplacements),
5152
concatMap(() => normalizeAssetPatterns(
5253
options.assets, host, root, projectRoot, builderConfig.sourceRoot)),
5354
// Replace the assets in options with the normalized version.

packages/angular_devkit/build_angular/src/server/index.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { WebpackBuilder } from '@angular-devkit/build-webpack';
1616
import { Path, getSystemPath, normalize, resolve, virtualFs } from '@angular-devkit/core';
1717
import { Stats } from 'fs';
1818
import { Observable, concat, of } from 'rxjs';
19-
import { concatMap, last } from 'rxjs/operators';
19+
import { concatMap, last, tap } from 'rxjs/operators';
2020
import * as ts from 'typescript'; // tslint:disable-line:no-implicit-dependencies
2121
import { WebpackConfigOptions } from '../angular-cli-files/models/build-options';
2222
import {
@@ -30,7 +30,7 @@ import {
3030
import { readTsconfig } from '../angular-cli-files/utilities/read-tsconfig';
3131
import { requireProjectModule } from '../angular-cli-files/utilities/require-project-module';
3232
import { getBrowserLoggingCb } from '../browser';
33-
import { addFileReplacements } from '../utils';
33+
import { normalizeFileReplacements } from '../utils';
3434
import { BuildWebpackServerSchema } from './schema';
3535
const webpackMerge = require('webpack-merge');
3636

@@ -51,7 +51,8 @@ export class ServerBuilder implements Builder<BuildWebpackServerSchema> {
5151
concatMap(() => options.deleteOutputPath
5252
? this._deleteOutputDir(root, normalize(options.outputPath), this.context.host)
5353
: of(null)),
54-
concatMap(() => addFileReplacements(root, host, options.fileReplacements)),
54+
concatMap(() => normalizeFileReplacements(options.fileReplacements, host, root)),
55+
tap(fileReplacements => options.fileReplacements = fileReplacements),
5556
concatMap(() => {
5657
const webpackConfig = this.buildWebpackConfig(root, projectRoot, host, options);
5758

packages/angular_devkit/build_angular/src/utils/add-file-replacements.ts

+59-41
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { BaseException, Path, join, normalize, virtualFs } from '@angular-devkit/core';
10-
import { Observable, forkJoin, of } from 'rxjs';
11-
import { map, tap } from 'rxjs/operators';
9+
import {
10+
BaseException,
11+
Path,
12+
getSystemPath,
13+
join,
14+
normalize,
15+
virtualFs,
16+
} from '@angular-devkit/core';
17+
import { Observable, from, of } from 'rxjs';
18+
import { concat, concatMap, ignoreElements, map, mergeMap, tap, toArray } from 'rxjs/operators';
1219
import {
1320
CurrentFileReplacement,
1421
DeprecatedFileReplacment,
@@ -22,53 +29,64 @@ export class MissingFileReplacementException extends BaseException {
2229
}
2330
}
2431

25-
// Note: This method changes the file replacements in place.
26-
export function addFileReplacements(
27-
root: Path,
28-
host: virtualFs.AliasHost,
29-
fileReplacements: FileReplacement[],
30-
): Observable<null> {
32+
export interface NormalizedFileReplacement {
33+
replace: Path;
34+
with: Path;
35+
}
3136

37+
export function normalizeFileReplacements(
38+
fileReplacements: FileReplacement[],
39+
host: virtualFs.Host,
40+
root: Path,
41+
): Observable<NormalizedFileReplacement[]> {
3242
if (fileReplacements.length === 0) {
33-
return of(null);
34-
}
35-
36-
// Normalize the legacy format into the current one.
37-
for (const fileReplacement of fileReplacements) {
38-
const currentFormat = fileReplacement as CurrentFileReplacement;
39-
const maybeOldFormat = fileReplacement as DeprecatedFileReplacment;
40-
41-
if (maybeOldFormat.src && maybeOldFormat.replaceWith) {
42-
currentFormat.replace = maybeOldFormat.src;
43-
currentFormat.with = maybeOldFormat.replaceWith;
44-
}
43+
return of([]);
4544
}
4645

47-
const normalizedFileReplacements = fileReplacements as CurrentFileReplacement[];
48-
4946
// Ensure all the replacements exist.
50-
const errorOnFalse = (path: string) => tap((exists: boolean) => {
47+
const errorOnFalse = (path: Path) => tap((exists: boolean) => {
5148
if (!exists) {
52-
throw new MissingFileReplacementException(path);
49+
throw new MissingFileReplacementException(getSystemPath(path));
5350
}
5451
});
5552

56-
const existObservables = normalizedFileReplacements
57-
.map(replacement => [
58-
host.exists(join(root, replacement.replace)).pipe(errorOnFalse(replacement.replace)),
59-
host.exists(join(root, replacement.with)).pipe(errorOnFalse(replacement.with)),
60-
])
61-
.reduce((prev, curr) => prev.concat(curr), []);
62-
63-
return forkJoin(existObservables).pipe(
64-
tap(() => {
65-
normalizedFileReplacements.forEach(replacement => {
66-
host.aliases.set(
67-
join(root, normalize(replacement.replace)),
68-
join(root, normalize(replacement.with)),
69-
);
70-
});
53+
return from(fileReplacements).pipe(
54+
map(replacement => normalizeFileReplacement(replacement, root)),
55+
concatMap(normalized => {
56+
return from([normalized.replace, normalized.with]).pipe(
57+
mergeMap(path => host.exists(path).pipe(errorOnFalse(path))),
58+
ignoreElements(),
59+
concat(of(normalized)),
60+
);
7161
}),
72-
map(() => null),
62+
toArray(),
7363
);
7464
}
65+
66+
function normalizeFileReplacement(
67+
fileReplacement: FileReplacement,
68+
root?: Path,
69+
): NormalizedFileReplacement {
70+
const currentFormat = fileReplacement as CurrentFileReplacement;
71+
const maybeOldFormat = fileReplacement as DeprecatedFileReplacment;
72+
73+
let replacePath: Path;
74+
let withPath: Path;
75+
if (maybeOldFormat.src && maybeOldFormat.replaceWith) {
76+
replacePath = normalize(maybeOldFormat.src);
77+
withPath = normalize(maybeOldFormat.replaceWith);
78+
} else {
79+
replacePath = normalize(currentFormat.replace);
80+
withPath = normalize(currentFormat.with);
81+
}
82+
83+
// TODO: For 7.x should this only happen if not absolute?
84+
if (root) {
85+
replacePath = join(root, replacePath);
86+
}
87+
if (root) {
88+
withPath = join(root, withPath);
89+
}
90+
91+
return { replace: replacePath, with: withPath };
92+
}

0 commit comments

Comments
 (0)