diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 26e982955f8c..00a06e496452 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -24,7 +24,7 @@ "peerDependencies": { "@angular/compiler-cli": "^14.0.0 || ^14.0.0-next", "typescript": "~4.6.2", - "webpack": "^5.30.0" + "webpack": "^5.54.0" }, "devDependencies": { "@angular-devkit/core": "0.0.0-PLACEHOLDER", diff --git a/packages/ngtools/webpack/src/ivy/plugin.ts b/packages/ngtools/webpack/src/ivy/plugin.ts index aaaf00a20a7b..8f62358cc998 100644 --- a/packages/ngtools/webpack/src/ivy/plugin.ts +++ b/packages/ngtools/webpack/src/ivy/plugin.ts @@ -8,7 +8,6 @@ import type { CompilerHost, CompilerOptions, NgtscProgram } from '@angular/compiler-cli'; import { strict as assert } from 'assert'; -import { createHash } from 'crypto'; import * as ts from 'typescript'; import type { Compilation, Compiler, Module, NormalModule } from 'webpack'; import { NgccProcessor } from '../ngcc_processor'; @@ -107,6 +106,7 @@ export class AngularWebpackPlugin { private builder?: ts.EmitAndSemanticDiagnosticsBuilderProgram; private sourceFileCache?: SourceFileCache; private webpackCache?: ReturnType; + private webpackCreateHash?: Compiler['webpack']['util']['createHash']; private readonly fileDependencies = new Map>(); private readonly requiredFilesToEmit = new Set(); private readonly requiredFilesToEmitCache = new Map(); @@ -141,6 +141,7 @@ export class AngularWebpackPlugin { // eslint-disable-next-line max-lines-per-function apply(compiler: Compiler): void { const { NormalModuleReplacementPlugin, util } = compiler.webpack; + this.webpackCreateHash = util.createHash; // Setup file replacements with webpack for (const [key, value] of Object.entries(this.pluginOptions.fileReplacements)) { @@ -745,9 +746,11 @@ export class AngularWebpackPlugin { filePath: string, content: string, ): Promise { + assert.ok(this.webpackCreateHash, 'File emitter is used prior to Webpack compilation'); + const historyData: FileEmitHistoryItem = { length: content.length, - hash: createHash('md5').update(content).digest(), + hash: this.webpackCreateHash('xxhash64').update(content).digest() as Uint8Array, }; if (this.webpackCache) { diff --git a/packages/ngtools/webpack/src/resource_loader.ts b/packages/ngtools/webpack/src/resource_loader.ts index 128ea1ca46d6..5219fd3dc812 100644 --- a/packages/ngtools/webpack/src/resource_loader.ts +++ b/packages/ngtools/webpack/src/resource_loader.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import { createHash } from 'crypto'; import * as path from 'path'; import * as vm from 'vm'; import type { Asset, Compilation } from 'webpack'; @@ -100,6 +99,7 @@ export class WebpackResourceLoader { this._reverseDependencies.set(file, new Set(resources)); } + // eslint-disable-next-line max-lines-per-function private async _compile( filePath?: string, data?: string, @@ -111,6 +111,16 @@ export class WebpackResourceLoader { throw new Error('WebpackResourceLoader cannot be used without parentCompilation'); } + const { context, webpack } = this._parentCompilation.compiler; + const { + EntryPlugin, + NormalModule, + library, + node, + sources, + util: { createHash }, + } = webpack; + const getEntry = (): string => { if (filePath) { return `${filePath}?${NG_COMPONENT_RESOURCE_QUERY}`; @@ -122,7 +132,9 @@ export class WebpackResourceLoader { ); } else if (data) { // Create a special URL for reading the resource from memory - return `angular-resource:${resourceType},${createHash('md5').update(data).digest('hex')}`; + return `angular-resource:${resourceType},${createHash('xxhash64') + .update(data) + .digest('hex')}`; } throw new Error(`"filePath", "resourceType" or "data" must be specified.`); @@ -150,8 +162,6 @@ export class WebpackResourceLoader { }, }; - const { context, webpack } = this._parentCompilation.compiler; - const { EntryPlugin, NormalModule, library, node, sources } = webpack; const childCompiler = this._parentCompilation.createChildCompiler( 'angular-compiler:resource', outputOptions,