Skip to content

Commit e31af46

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

File tree

9 files changed

+122
-86
lines changed

9 files changed

+122
-86
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

-74
This file was deleted.

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
*/
88

99
export * from './run-module-as-observable-fork';
10-
export * from './add-file-replacements';
10+
export * from './normalize-file-replacements';
1111
export * from './normalize-asset-patterns';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
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';
19+
import {
20+
CurrentFileReplacement,
21+
DeprecatedFileReplacment,
22+
FileReplacement,
23+
} from '../browser/schema';
24+
25+
26+
export class MissingFileReplacementException extends BaseException {
27+
constructor(path: String) {
28+
super(`The ${path} path in file replacements does not exist.`);
29+
}
30+
}
31+
32+
export interface NormalizedFileReplacement {
33+
replace: Path;
34+
with: Path;
35+
}
36+
37+
export function normalizeFileReplacements(
38+
fileReplacements: FileReplacement[],
39+
host: virtualFs.Host,
40+
root: Path,
41+
): Observable<NormalizedFileReplacement[]> {
42+
if (fileReplacements.length === 0) {
43+
return of([]);
44+
}
45+
46+
// Ensure all the replacements exist.
47+
const errorOnFalse = (path: Path) => tap((exists: boolean) => {
48+
if (!exists) {
49+
throw new MissingFileReplacementException(getSystemPath(path));
50+
}
51+
});
52+
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+
);
61+
}),
62+
toArray(),
63+
);
64+
}
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)