diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/browser.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/browser.ts index f672b5b0fe..195cc9be93 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/browser.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/browser.ts @@ -62,7 +62,7 @@ export function getBrowserConfig(wco: WebpackConfigOptions): webpack.Configurati const globalStylesBundleNames = normalizeExtraEntryPoints(styles, 'styles') .map(style => style.bundleName); - let crossOriginLoading: string | false = false; + let crossOriginLoading: 'anonymous' | 'use-credentials' | false = false; if (subresourceIntegrity && crossOrigin === 'none') { crossOriginLoading = 'anonymous'; } else if (crossOrigin !== 'none') { diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts index 73a1a72645..7673c598a0 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/common.ts @@ -16,14 +16,12 @@ import * as path from 'path'; import { RollupOptions } from 'rollup'; import { ScriptTarget } from 'typescript'; import { - ChunkData, Compiler, Configuration, ContextReplacementPlugin, - HashedModuleIdsPlugin, - Plugin, - Rule, RuleSetLoader, + RuleSetRule, + compilation, debug, } from 'webpack'; import { RawSource } from 'webpack-sources'; @@ -64,9 +62,9 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { vendor: vendorSourceMap, } = buildOptions.sourceMap; - const extraPlugins: Plugin[] = []; - const extraRules: Rule[] = []; - const entryPoints: { [key: string]: string[] } = {}; + const extraPlugins: { apply(compiler: Compiler): void }[] = []; + const extraRules: RuleSetRule[] = []; + const entryPoints: { [key: string]: [string, ...string[]] } = {}; // determine hashing format const hashFormat = getOutputHashFormat(buildOptions.outputHashing || 'none'); @@ -150,7 +148,10 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { // tslint:disable-next-line: no-any (compilation.mainTemplate.hooks as any).assetPath.tap( 'build-angular', - (filename: string | ((data: ChunkData) => string), data: ChunkData) => { + ( + filename: string | ((data: { chunk: compilation.Chunk }) => string), + data: { chunk: compilation.Chunk }, + ) => { const assetName = typeof filename === 'function' ? filename(data) : filename; const isMap = assetName && assetName.endsWith('.map'); @@ -177,17 +178,21 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { } if (buildOptions.polyfills) { - entryPoints['polyfills'] = [ - ...(entryPoints['polyfills'] || []), - path.resolve(root, buildOptions.polyfills), - ]; + const projectPolyfills = path.resolve(root, buildOptions.polyfills); + if (entryPoints['polyfills']) { + entryPoints['polyfills'].push(projectPolyfills); + } else { + entryPoints['polyfills'] = [projectPolyfills]; + } } if (!buildOptions.aot) { - entryPoints['polyfills'] = [ - ...(entryPoints['polyfills'] || []), - path.join(__dirname, '..', 'jit-polyfills.js'), - ]; + const jitPolyfills = path.join(__dirname, '..', 'jit-polyfills.js'); + if (entryPoints['polyfills']) { + entryPoints['polyfills'].push(jitPolyfills); + } else { + entryPoints['polyfills'] = [jitPolyfills]; + } } } @@ -592,8 +597,9 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { ], }, optimization: { + minimizer: extraMinimizers, + moduleIds: 'hashed', noEmitOnErrors: true, - minimizer: [new HashedModuleIdsPlugin(), ...extraMinimizers], }, plugins: [ // Always replace the context for the System.import in angular/core to prevent warnings. diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/styles.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/styles.ts index 04333b4d6b..249653d6b4 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/styles.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/styles.ts @@ -24,11 +24,11 @@ const postcssImports = require('postcss-import'); // tslint:disable-next-line:no-big-function export function getStylesConfig(wco: WebpackConfigOptions) { const { root, buildOptions } = wco; - const entryPoints: { [key: string]: string[] } = {}; + const entryPoints: { [key: string]: [string, ...string[]] } = {}; const globalStylePaths: string[] = []; - const extraPlugins: webpack.Plugin[] = [ - new AnyComponentStyleBudgetChecker(buildOptions.budgets), - ]; + const extraPlugins: { apply(compiler: webpack.Compiler): void }[] = []; + + extraPlugins.push(new AnyComponentStyleBudgetChecker(buildOptions.budgets)); const cssSourceMap = buildOptions.sourceMap.styles; diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/test.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/test.ts index 8a2a7869d8..166b5d5cf2 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/test.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/test.ts @@ -17,8 +17,8 @@ export function getTestConfig( ): webpack.Configuration { const { root, buildOptions, sourceRoot: include } = wco; - const extraRules: webpack.Rule[] = []; - const extraPlugins: webpack.Plugin[] = []; + const extraRules: webpack.RuleSetRule[] = []; + const extraPlugins: { apply(compiler: webpack.Compiler): void }[] = []; if (buildOptions.codeCoverage) { const codeCoverageExclude = buildOptions.codeCoverageExclude; diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/any-component-style-budget-checker.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/any-component-style-budget-checker.ts index fb311e45d4..2717bf0864 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/any-component-style-budget-checker.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/any-component-style-budget-checker.ts @@ -7,7 +7,7 @@ */ import * as path from 'path'; -import { Compiler, Plugin } from 'webpack'; +import { Compiler } from 'webpack'; import { Budget, Type } from '../../../src/browser/schema'; import { ThresholdSeverity, calculateThresholds, checkThresholds } from '../utilities/bundle-calculator'; @@ -17,7 +17,7 @@ const PLUGIN_NAME = 'AnyComponentStyleBudgetChecker'; * Check budget sizes for component styles by emitting a warning or error if a * budget is exceeded by a particular component's styles. */ -export class AnyComponentStyleBudgetChecker implements Plugin { +export class AnyComponentStyleBudgetChecker { private readonly budgets: Budget[]; constructor(budgets: Budget[]) { this.budgets = budgets.filter((budget) => budget.type === Type.AnyComponentStyle); diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/bundle-budget.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/bundle-budget.ts index 3d3a56b7e7..d68157e131 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/bundle-budget.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/bundle-budget.ts @@ -5,7 +5,7 @@ * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -import { Compiler, compilation } from 'webpack'; +import { Compiler } from 'webpack'; import { Budget } from '../../browser/schema'; import { ProcessBundleResult } from '../../utils/process-bundle'; import { ThresholdSeverity, checkBudgets } from '../utilities/bundle-calculator'; @@ -24,26 +24,22 @@ export class BundleBudgetPlugin { return; } - compiler.hooks.afterEmit.tap('BundleBudgetPlugin', (compilation: compilation.Compilation) => { - this.runChecks(budgets, compilation); + compiler.hooks.afterEmit.tap('BundleBudgetPlugin', (compilation) => { + // No process bundle results because this plugin is only used when differential + // builds are disabled. + const processResults: ProcessBundleResult[] = []; + + const stats = compilation.getStats().toJson(); + for (const { severity, message } of checkBudgets(budgets, stats, processResults)) { + switch (severity) { + case ThresholdSeverity.Warning: + compilation.warnings.push(`budgets: ${message}`); + break; + case ThresholdSeverity.Error: + compilation.errors.push(`budgets: ${message}`); + break; + } + } }); } - - private runChecks(budgets: Budget[], compilation: compilation.Compilation) { - // No process bundle results because this plugin is only used when differential - // builds are disabled. - const processResults: ProcessBundleResult[] = []; - - const stats = compilation.getStats().toJson(); - for (const { severity, message } of checkBudgets(budgets, stats, processResults)) { - switch (severity) { - case ThresholdSeverity.Warning: - compilation.warnings.push(`budgets: ${message}`); - break; - case ThresholdSeverity.Error: - compilation.errors.push(`budgets: ${message}`); - break; - } - } - } } diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/index-html-webpack-plugin.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/index-html-webpack-plugin.ts index 9f6a5cc2d7..0c54571bb8 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/index-html-webpack-plugin.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/index-html-webpack-plugin.ts @@ -88,7 +88,11 @@ export class IndexHtmlWebpackPlugin { } } - const loadOutputFile = (name: string) => compilation.assets[name].source(); + const loadOutputFile = async (name: string) => { + const data = compilation.assets[name].source(); + + return typeof data === 'string' ? data : data.toString(); + }; let indexSource = await augmentIndexHtml({ input: this._options.input, inputContent, diff --git a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/optimize-css-webpack-plugin.ts b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/optimize-css-webpack-plugin.ts index 7296e5c552..fddabc6e82 100644 --- a/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/optimize-css-webpack-plugin.ts +++ b/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/optimize-css-webpack-plugin.ts @@ -19,17 +19,14 @@ function hook( compiler: Compiler, action: ( compilation: compilation.Compilation, - chunks: compilation.Chunk[], - ) => Promise, + chunks: Iterable, + ) => Promise, ) { - compiler.hooks.compilation.tap( - 'optimize-css-webpack-plugin', - (compilation: compilation.Compilation) => { - compilation.hooks.optimizeChunkAssets.tapPromise('optimize-css-webpack-plugin', chunks => - action(compilation, chunks), - ); - }, - ); + compiler.hooks.compilation.tap('optimize-css-webpack-plugin', (compilation) => { + compilation.hooks.optimizeChunkAssets.tapPromise('optimize-css-webpack-plugin', (chunks) => + action(compilation, chunks), + ); + }); } export class OptimizeCssWebpackPlugin { @@ -44,14 +41,18 @@ export class OptimizeCssWebpackPlugin { } apply(compiler: Compiler): void { - hook(compiler, (compilation: compilation.Compilation, chunks: compilation.Chunk[]) => { + hook(compiler, (compilation: compilation.Compilation, chunks: Iterable) => { const files: string[] = [...compilation.additionalChunkAssets]; - chunks.forEach(chunk => { - if (chunk.files && chunk.files.length > 0) { - files.push(...chunk.files); + for (const chunk of chunks) { + if (!chunk.files) { + continue; } - }); + + for (const file of chunk.files) { + files.push(file); + } + } const actions = files .filter(file => this._options.test(file)) @@ -120,7 +121,7 @@ export class OptimizeCssWebpackPlugin { compilation.assets[file] = newSource; }); - return Promise.all(actions); + return Promise.all(actions).then(() => {}); }); } }