Skip to content
This repository was archived by the owner on Apr 4, 2025. It is now read-only.

Commit 3d809ef

Browse files
filipesilvahansl
authored andcommitted
fix(@angular-devkit/build-angular): validate fileReplacements, allow string styles/scripts
Fix angular/angular-cli#5053 Fix angular/angular-cli#10267
1 parent 799b2fa commit 3d809ef

File tree

30 files changed

+886
-485
lines changed

30 files changed

+886
-485
lines changed

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

+6-21
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
// tslint:disable-next-line:no-implicit-dependencies
1212
import * as ts from 'typescript';
13-
import { Budget } from '../utilities/bundle-calculator';
13+
import { AssetPattern, Budget, ExtraEntryPoint } from '../../browser/schema';
1414

1515
export interface BuildOptions {
1616
optimization: boolean;
@@ -27,8 +27,6 @@ export interface BuildOptions {
2727
progress?: boolean;
2828
i18nFile?: string;
2929
i18nFormat?: string;
30-
i18nOutFile?: string;
31-
i18nOutFormat?: string;
3230
i18nLocale?: string;
3331
i18nMissingTranslation?: string;
3432
extractCss?: boolean;
@@ -56,34 +54,21 @@ export interface BuildOptions {
5654
assets: AssetPattern[];
5755
scripts: ExtraEntryPoint[];
5856
styles: ExtraEntryPoint[];
59-
stylePreprocessorOptions: { includePaths: string[] };
57+
stylePreprocessorOptions?: { includePaths: string[] };
6058
lazyModules: string[];
6159
platform?: 'browser' | 'server';
6260
}
6361

64-
export interface AssetPattern {
65-
glob: string;
66-
input: string;
67-
output: string;
68-
allowOutsideOutDir?: boolean;
69-
}
70-
71-
export interface ExtraEntryPoint {
72-
input: string;
73-
output?: string;
74-
lazy: boolean;
62+
export interface WebpackTestOptions extends BuildOptions {
63+
codeCoverage?: boolean;
64+
codeCoverageExclude?: string[];
7565
}
7666

77-
export interface WebpackConfigOptions<T extends BuildOptions = BuildOptions> {
67+
export interface WebpackConfigOptions<T = BuildOptions> {
7868
root: string;
7969
projectRoot: string;
8070
buildOptions: T;
8171
tsConfig: ts.ParsedCommandLine;
8272
tsConfigPath: string;
8373
supportES2015: boolean;
8474
}
85-
86-
export interface WebpackTestOptions extends BuildOptions {
87-
codeCoverage?: boolean;
88-
codeCoverageExclude?: string[];
89-
}

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

+9-7
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import { LicenseWebpackPlugin } from 'license-webpack-plugin';
88
import { generateEntryPoints, packageChunkSort } from '../../utilities/package-chunk-sort';
99
import { BaseHrefWebpackPlugin } from '../../lib/base-href-webpack';
1010
import { IndexHtmlWebpackPlugin } from '../../plugins/index-html-webpack-plugin';
11-
import { ExtraEntryPoint } from '../../../browser';
11+
import { ExtraEntryPoint } from '../../../browser/schema';
12+
import { BrowserBuilderSchema } from '../../../browser/schema';
1213
import { WebpackConfigOptions } from '../build-options';
13-
import { computeBundleName } from './utils';
14+
import { normalizeExtraEntryPoints } from './utils';
1415

1516
/**
1617
+ * license-webpack-plugin has a peer dependency on webpack-sources, list it in a comment to
@@ -26,10 +27,11 @@ export function getBrowserConfig(wco: WebpackConfigOptions) {
2627
let extraPlugins: any[] = [];
2728

2829
// Figure out which are the lazy loaded bundle names.
29-
const lazyChunkBundleNames = ([...buildOptions.styles, ...buildOptions.scripts] as ExtraEntryPoint[])
30-
.filter(entry => entry.lazy)
30+
const lazyChunkBundleNames = normalizeExtraEntryPoints(
3131
// We don't really need a default name because we pre-filtered by lazy only entries.
32-
.map(style => computeBundleName(style, 'not-lazy'));
32+
[...buildOptions.styles, ...buildOptions.scripts], 'not-lazy')
33+
.filter(entry => entry.lazy)
34+
.map(entry => entry.bundleName)
3335

3436
const generateIndexHtml = false;
3537
if (generateIndexHtml) {
@@ -77,8 +79,8 @@ export function getBrowserConfig(wco: WebpackConfigOptions) {
7779
}));
7880
}
7981

80-
const globalStylesBundleNames = (buildOptions.styles as ExtraEntryPoint[])
81-
.map(style => computeBundleName(style, 'styles'));
82+
const globalStylesBundleNames = normalizeExtraEntryPoints(buildOptions.styles, 'styles')
83+
.map(style => style.bundleName);
8284

8385
return {
8486
devtool: sourcemaps,

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import { BundleBudgetPlugin } from '../../plugins/bundle-budget';
1212
import { CleanCssWebpackPlugin } from '../../plugins/cleancss-webpack-plugin';
1313
import { ScriptsWebpackPlugin } from '../../plugins/scripts-webpack-plugin';
1414
import { findUp } from '../../utilities/find-up';
15-
import { AssetPattern, ExtraEntryPoint } from '../../../browser';
16-
import { computeBundleName } from './utils';
15+
import { AssetPattern, ExtraEntryPoint } from '../../../browser/schema';
16+
import { normalizeExtraEntryPoints } from './utils';
1717

1818
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
1919
const CircularDependencyPlugin = require('circular-dependency-plugin');
@@ -63,9 +63,9 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
6363

6464
// process global scripts
6565
if (buildOptions.scripts.length > 0) {
66-
const globalScriptsByBundleName = (buildOptions.scripts as ExtraEntryPoint[])
66+
const globalScriptsByBundleName = normalizeExtraEntryPoints(buildOptions.scripts, 'scripts')
6767
.reduce((prev: { bundleName: string, paths: string[], lazy: boolean }[], curr) => {
68-
const bundleName = computeBundleName(curr, 'scripts');
68+
const bundleName = curr.bundleName;
6969
const resolvedPath = path.resolve(root, curr.input);
7070
let existingEntry = prev.find((el) => el.bundleName === bundleName);
7171
if (existingEntry) {

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

+6-7
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { getOutputHashFormat } from './utils';
88
import { WebpackConfigOptions } from '../build-options';
99
import { findUp } from '../../utilities/find-up';
1010
import { RawCssLoader } from '../../plugins/webpack';
11-
import { ExtraEntryPoint } from '../../../browser';
12-
import { computeBundleName } from './utils';
11+
import { ExtraEntryPoint } from '../../../browser/schema';
12+
import { normalizeExtraEntryPoints } from './utils';
1313

1414
const postcssUrl = require('postcss-url');
1515
const autoprefixer = require('autoprefixer');
@@ -166,15 +166,14 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
166166

167167
// Process global styles.
168168
if (buildOptions.styles.length > 0) {
169-
(buildOptions.styles as ExtraEntryPoint[]).forEach(style => {
170-
const bundleName = computeBundleName(style, 'styles');;
169+
normalizeExtraEntryPoints(buildOptions.styles, 'styles').forEach(style => {
171170
const resolvedPath = path.resolve(root, style.input);
172171

173172
// Add style entry points.
174-
if (entryPoints[bundleName]) {
175-
entryPoints[bundleName].push(resolvedPath)
173+
if (entryPoints[style.bundleName]) {
174+
entryPoints[style.bundleName].push(resolvedPath)
176175
} else {
177-
entryPoints[bundleName] = [resolvedPath]
176+
entryPoints[style.bundleName] = [resolvedPath]
178177
}
179178

180179
// Add global css paths.

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

+17-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ function _createAotPlugin(
2525
options: any,
2626
host: virtualFs.Host<Stats>,
2727
useMain = true,
28+
extract = false
2829
) {
2930
const { root, buildOptions } = wco;
3031
options.compilerOptions = options.compilerOptions || {};
@@ -37,6 +38,15 @@ function _createAotPlugin(
3738
? path.resolve(root, buildOptions.i18nFile)
3839
: undefined;
3940

41+
const i18nFileAndFormat = extract
42+
? {
43+
i18nOutFile: buildOptions.i18nFile,
44+
i18nOutFormat: buildOptions.i18nFormat,
45+
} : {
46+
i18nInFile: i18nInFile,
47+
i18nInFormat: buildOptions.i18nFormat,
48+
};
49+
4050
const additionalLazyModules: { [module: string]: string } = {};
4151
if (buildOptions.lazyModules) {
4252
for (const lazyModule of buildOptions.lazyModules) {
@@ -49,10 +59,7 @@ function _createAotPlugin(
4959

5060
const pluginOptions: AngularCompilerPluginOptions = {
5161
mainPath: useMain ? path.join(root, buildOptions.main) : undefined,
52-
i18nInFile: i18nInFile,
53-
i18nInFormat: buildOptions.i18nFormat,
54-
i18nOutFile: buildOptions.i18nOutFile,
55-
i18nOutFormat: buildOptions.i18nOutFormat,
62+
...i18nFileAndFormat,
5663
locale: buildOptions.i18nLocale,
5764
platform: buildOptions.platform === 'server' ? PLATFORM.Server : PLATFORM.Browser,
5865
missingTranslation: buildOptions.i18nMissingTranslation,
@@ -75,7 +82,11 @@ export function getNonAotConfig(wco: WebpackConfigOptions, host: virtualFs.Host<
7582
};
7683
}
7784

78-
export function getAotConfig(wco: WebpackConfigOptions, host: virtualFs.Host<Stats>) {
85+
export function getAotConfig(
86+
wco: WebpackConfigOptions,
87+
host: virtualFs.Host<Stats>,
88+
extract = false
89+
) {
7990
const { tsConfigPath, buildOptions } = wco;
8091

8192
const loaders: any[] = [webpackLoader];
@@ -90,7 +101,7 @@ export function getAotConfig(wco: WebpackConfigOptions, host: virtualFs.Host<Sta
90101

91102
return {
92103
module: { rules: [{ test, use: loaders }] },
93-
plugins: [_createAotPlugin(wco, { tsConfigPath }, host)]
104+
plugins: [_createAotPlugin(wco, { tsConfigPath }, host, true, extract)]
94105
};
95106
}
96107

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

+30-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import * as path from 'path';
55
import { basename, normalize } from '@angular-devkit/core';
6-
import { ExtraEntryPoint } from '../../../browser';
6+
import { ExtraEntryPoint, ExtraEntryPointObject } from '../../../browser/schema';
77

88
export const ngAppResolve = (resolvePath: string): string => {
99
return path.resolve(process.cwd(), resolvePath);
@@ -61,14 +61,34 @@ export function getOutputHashFormat(option: string, length = 20): HashFormat {
6161
return hashFormats[option] || hashFormats['none'];
6262
}
6363

64-
export function computeBundleName(entry: ExtraEntryPoint, defaultName: string){
65-
if (entry.bundleName) {
66-
return entry.bundleName;
67-
} else if (entry.lazy) {
68-
return basename(
69-
normalize(entry.input.replace(/\.(js|css|scss|sass|less|styl)$/i, '')),
70-
);
64+
export type NormalizedEntryPoint = ExtraEntryPointObject & { bundleName: string };
65+
66+
export function normalizeExtraEntryPoints(
67+
extraEntryPoints: ExtraEntryPoint[],
68+
defaultBundleName: string
69+
): NormalizedEntryPoint[] {
70+
return extraEntryPoints.map(entry => {
71+
let normalizedEntry;
72+
73+
if (typeof entry === 'string') {
74+
normalizedEntry = { input: entry, lazy: false, bundleName: defaultBundleName };
7175
} else {
72-
return defaultName;
73-
}
76+
let bundleName;
77+
78+
if (entry.bundleName) {
79+
bundleName = entry.bundleName;
80+
} else if (entry.lazy) {
81+
// Lazy entry points use the file name as bundle name.
82+
bundleName = basename(
83+
normalize(entry.input.replace(/\.(js|css|scss|sass|less|styl)$/i, '')),
84+
);
85+
} else {
86+
bundleName = defaultBundleName;
87+
}
88+
89+
normalizedEntry = {...entry, bundleName};
90+
}
91+
92+
return normalizedEntry;
93+
})
7494
}

packages/angular_devkit/build_angular/src/angular-cli-files/plugins/bundle-budget.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
* found in the LICENSE file at https://angular.io/license
1010
*/
1111

12-
import { Budget, Size, calculateBytes, calculateSizes } from '../utilities/bundle-calculator';
12+
import { Size, calculateBytes, calculateSizes } from '../utilities/bundle-calculator';
13+
import { Budget } from '../../browser/schema';
1314
import { formatSize } from '../utilities/stats';
1415

1516
interface Thresholds {

packages/angular_devkit/build_angular/src/angular-cli-files/plugins/karma.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as glob from 'glob';
77
import * as webpack from 'webpack';
88
const webpackDevMiddleware = require('webpack-dev-middleware');
99

10-
import { AssetPattern } from '../../browser';
10+
import { AssetPattern } from '../../browser/schema';
1111
import { KarmaWebpackFailureCb } from './karma-webpack-failure-cb';
1212

1313
/**

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/bundle-calculator.ts

+1-40
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,7 @@
88
* Use of this source code is governed by an MIT-style license that can be
99
* found in the LICENSE file at https://angular.io/license
1010
*/
11-
export type BudgetType = 'all' | 'allScript' | 'any' | 'anyScript' | 'bundle' | 'initial';
12-
13-
export interface Budget {
14-
/**
15-
* The type of budget
16-
*/
17-
type: BudgetType;
18-
/**
19-
* The name of the bundle
20-
*/
21-
name?: string;
22-
/**
23-
* The baseline size for comparison.
24-
*/
25-
baseline?: string;
26-
/**
27-
* The maximum threshold for warning relative to the baseline.
28-
*/
29-
maximumWarning?: string;
30-
/**
31-
* The maximum threshold for error relative to the baseline.
32-
*/
33-
maximumError?: string;
34-
/**
35-
* The minimum threshold for warning relative to the baseline.
36-
*/
37-
minimumWarning?: string;
38-
/**
39-
* The minimum threshold for error relative to the baseline.
40-
*/
41-
minimumError?: string;
42-
/**
43-
* The threshold for warning relative to the baseline (min & max).
44-
*/
45-
warning?: string;
46-
/**
47-
* The threshold for error relative to the baseline (min & max).
48-
*/
49-
error?: string;
50-
}
11+
import { Budget } from '../../browser/schema';
5112

5213
export interface Compilation {
5314
assets: any;

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/package-chunk-sort.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
// tslint:disable
22
// TODO: cleanup this file, it's copied as is from Angular CLI.
33

4-
import { ExtraEntryPoint } from '../../browser';
5-
import { computeBundleName } from '../models/webpack-configs/utils';
4+
import { ExtraEntryPoint } from '../../browser/schema';
5+
import { normalizeExtraEntryPoints } from '../models/webpack-configs/utils';
66

77
export function generateEntryPoints(appConfig: any) {
88
let entryPoints = ['polyfills', 'sw-register'];
99

1010
// Add all styles/scripts, except lazy-loaded ones.
1111
[
12-
...(appConfig.styles as ExtraEntryPoint[])
12+
...normalizeExtraEntryPoints(appConfig.styles as ExtraEntryPoint[], 'styles')
1313
.filter(entry => !entry.lazy)
14-
.map(entry => computeBundleName(entry, 'styles')),
15-
...(appConfig.scripts as ExtraEntryPoint[])
14+
.map(entry => entry.bundleName),
15+
...normalizeExtraEntryPoints(appConfig.scripts as ExtraEntryPoint[], 'scripts')
1616
.filter(entry => !entry.lazy)
17-
.map(entry => computeBundleName(entry, 'scripts')),
17+
.map(entry => entry.bundleName),
1818
].forEach(bundleName => {
1919
if (entryPoints.indexOf(bundleName) === -1) {
2020
entryPoints.push(bundleName);

0 commit comments

Comments
 (0)