From 28abfe7a5a4ddf689d78897563b16518bf126d0f Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:29:20 -0400 Subject: [PATCH] fix(@angular-devkit/build-angular): replace Webpack 4 `hashForChunk` hook usage Webpack 5 now uses a `chunkHash` hook that is accessible from `JavascriptModulesPlugin.getCompilationHooks()`. The `hashForChunk` hooks have been deprecated in Webpack 5. --- .../src/utils/webpack-browser-config.ts | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts b/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts index d8831849c6fa..d9890f05df16 100644 --- a/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts +++ b/packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts @@ -13,7 +13,7 @@ import { resolve, } from '@angular-devkit/core'; import * as path from 'path'; -import * as webpack from 'webpack'; +import { Configuration, JavascriptModulesPlugin } from 'webpack'; import { merge as webpackMerge } from 'webpack-merge'; import { Schema as BrowserBuilderSchema } from '../browser/schema'; import { @@ -33,10 +33,10 @@ export async function generateWebpackConfig( projectRoot: string, sourceRoot: string | undefined, options: NormalizedBrowserBuilderSchema, - webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => webpack.Configuration[], + webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => Configuration[], logger: logging.LoggerApi, extraBuildOptions: Partial, -): Promise { +): Promise { // Ensure Build Optimizer is only used with AOT. if (options.buildOptimizer && !options.aot) { throw new Error(`The 'buildOptimizer' option cannot be used without 'aot'.`); @@ -70,9 +70,9 @@ export async function generateWebpackConfig( export async function generateI18nBrowserWebpackConfigFromContext( options: BrowserBuilderSchema, context: BuilderContext, - webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => webpack.Configuration[], + webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => Configuration[], extraBuildOptions: Partial = {}, -): Promise<{ config: webpack.Configuration; projectRoot: string; projectSourceRoot?: string, i18n: I18nOptions }> { +): Promise<{ config: Configuration; projectRoot: string; projectSourceRoot?: string, i18n: I18nOptions }> { const { buildOptions, i18n } = await configureI18nBuild(context, options); const result = await generateBrowserWebpackConfigFromContext( buildOptions, @@ -106,25 +106,14 @@ export async function generateI18nBrowserWebpackConfigFromContext( (data, locale) => data + locale.files.map((file) => file.integrity || '').join('|'), '', ); - if (!config.plugins) { - config.plugins = []; - } + + config.plugins ??= []; config.plugins.push({ - apply(compiler: webpack.Compiler) { + apply(compiler) { compiler.hooks.compilation.tap('build-angular', compilation => { - // Webpack typings do not contain template hashForChunk hook - // tslint:disable-next-line: no-any - (compilation.mainTemplate.hooks as any).hashForChunk.tap( - 'build-angular', - (hash: { update(data: string): void }) => { - hash.update('$localize' + i18nHash); - }, - ); - // Webpack typings do not contain hooks property - // tslint:disable-next-line: no-any - (compilation.chunkTemplate as any).hooks.hashForChunk.tap( + JavascriptModulesPlugin.getCompilationHooks(compilation).chunkHash.tap( 'build-angular', - (hash: { update(data: string): void }) => { + (_, hash) => { hash.update('$localize' + i18nHash); }, ); @@ -138,9 +127,9 @@ export async function generateI18nBrowserWebpackConfigFromContext( export async function generateBrowserWebpackConfigFromContext( options: BrowserBuilderSchema, context: BuilderContext, - webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => webpack.Configuration[], + webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => Configuration[], extraBuildOptions: Partial = {}, -): Promise<{ config: webpack.Configuration; projectRoot: string; projectSourceRoot?: string }> { +): Promise<{ config: Configuration; projectRoot: string; projectSourceRoot?: string }> { const projectName = context.target && context.target.project; if (!projectName) { throw new Error('The builder requires a target.');