From d5645675fd555e7f1afd523d4f2d42095034fc46 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 16 Mar 2021 11:31:13 -0400 Subject: [PATCH] fix(@angular-devkit/build-angular): support writing large Webpack stat outputs When using the `statsJson` browser builder option, the resulting JSON data is now streamed into a file instead of written in one large block. This mitigates crashes due to the generated string exceeded the Node.js limit. --- package.json | 1 + .../angular_devkit/build_angular/BUILD.bazel | 1 + .../angular_devkit/build_angular/package.json | 1 + .../build_angular/src/babel-bazel.d.ts | 22 +++++++++++++++++++ .../build_angular/src/typings.d.ts | 16 ++------------ .../src/webpack/configs/common.ts | 17 +++++++++----- tsconfig.json | 2 +- yarn.lock | 6 ++++- 8 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 packages/angular_devkit/build_angular/src/babel-bazel.d.ts diff --git a/package.json b/package.json index 0f5c81091b23..358470cfadb8 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "@bazel/buildifier": "4.0.1", "@bazel/jasmine": "3.2.2", "@bazel/typescript": "3.2.2", + "@discoveryjs/json-ext": "0.5.2", "@jsdevtools/coverage-istanbul-loader": "3.0.5", "@types/babel__core": "7.1.13", "@types/babel__template": "7.4.0", diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index e34e50b84a55..1142122d29bc 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -113,6 +113,7 @@ ts_library( "@npm//@babel/preset-env", "@npm//@babel/runtime", "@npm//@babel/template", + "@npm//@discoveryjs/json-ext", "@npm//@jsdevtools/coverage-istanbul-loader", "@npm//@types/babel__core", "@npm//@types/babel__template", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 39a98b77892e..2d0b3469257f 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -18,6 +18,7 @@ "@babel/preset-env": "7.13.9", "@babel/runtime": "7.13.9", "@babel/template": "7.12.13", + "@discoveryjs/json-ext": "0.5.2", "@jsdevtools/coverage-istanbul-loader": "3.0.5", "@ngtools/webpack": "0.0.0", "ansi-colors": "4.1.1", diff --git a/packages/angular_devkit/build_angular/src/babel-bazel.d.ts b/packages/angular_devkit/build_angular/src/babel-bazel.d.ts new file mode 100644 index 000000000000..9a5d06cfa771 --- /dev/null +++ b/packages/angular_devkit/build_angular/src/babel-bazel.d.ts @@ -0,0 +1,22 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * 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 + */ + +// Workaround for https://github.com/bazelbuild/rules_nodejs/issues/1033 +// Alternative approach instead of https://github.com/angular/angular/pull/33226 +declare module '@babel/core' { + export * from '@types/babel__core'; +} +declare module '@babel/generator' { + export { default } from '@types/babel__generator'; +} +declare module '@babel/traverse' { + export { default } from '@types/babel__traverse'; +} +declare module '@babel/template' { + export { default } from '@types/babel__template'; +} diff --git a/packages/angular_devkit/build_angular/src/typings.d.ts b/packages/angular_devkit/build_angular/src/typings.d.ts index 9a5d06cfa771..bdf566191697 100644 --- a/packages/angular_devkit/build_angular/src/typings.d.ts +++ b/packages/angular_devkit/build_angular/src/typings.d.ts @@ -5,18 +5,6 @@ * 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 */ - -// Workaround for https://github.com/bazelbuild/rules_nodejs/issues/1033 -// Alternative approach instead of https://github.com/angular/angular/pull/33226 -declare module '@babel/core' { - export * from '@types/babel__core'; -} -declare module '@babel/generator' { - export { default } from '@types/babel__generator'; -} -declare module '@babel/traverse' { - export { default } from '@types/babel__traverse'; -} -declare module '@babel/template' { - export { default } from '@types/babel__template'; +declare module '@discoveryjs/json-ext' { + export function stringifyStream(value: unknown): import('stream').Readable; } diff --git a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts index 6da5d9946cca..89fdeb03bf0e 100644 --- a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts +++ b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts @@ -10,7 +10,7 @@ import { buildOptimizerLoaderPath, } from '@angular-devkit/build-optimizer'; import * as CopyWebpackPlugin from 'copy-webpack-plugin'; -import { existsSync } from 'fs'; +import { createWriteStream, existsSync } from 'fs'; import * as path from 'path'; import { ScriptTarget } from 'typescript'; import { @@ -21,7 +21,6 @@ import { compilation, debug, } from 'webpack'; -import { RawSource } from 'webpack-sources'; import { AssetPatternClass } from '../../browser/schema'; import { BuildBrowserFeatures, maxWorkers } from '../../utils'; import { WebpackConfigOptions } from '../../utils/build-options'; @@ -290,9 +289,17 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { extraPlugins.push( new (class { apply(compiler: Compiler) { - compiler.hooks.emit.tap('angular-cli-stats', compilation => { - const data = JSON.stringify(compilation.getStats().toJson('verbose'), undefined, 2); - compilation.assets['stats.json'] = new RawSource(data); + compiler.hooks.done.tapPromise('angular-cli-stats', async (stats) => { + const { stringifyStream } = await import('@discoveryjs/json-ext'); + const data = stats.toJson('verbose'); + const statsOutputPath = path.join(stats.compilation.outputOptions.path, 'stats.json'); + + return new Promise((resolve, reject) => + stringifyStream(data) + .pipe(createWriteStream(statsOutputPath)) + .on('close', resolve) + .on('error', reject), + ); }); } })(), diff --git a/tsconfig.json b/tsconfig.json index b71466f352ca..89085933c744 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -57,7 +57,7 @@ "suppressTsconfigOverrideWarnings": true }, "exclude": [ - "packages/angular_devkit/build_angular/src/typings.d.ts", + "packages/angular_devkit/build_angular/src/bazel-babel.d.ts", "bazel-out/**/*", "dist/**/*", "dist-schema/**", diff --git a/yarn.lock b/yarn.lock index 473f6410c7eb..0902d8b16c5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -87,7 +87,6 @@ "@angular/dev-infra-private@https://github.com/angular/dev-infra-private-builds.git#a6b42dabedcf7c724bd36a614ebe9fa99c777e62": version "0.0.0" - uid a6b42dabedcf7c724bd36a614ebe9fa99c777e62 resolved "https://github.com/angular/dev-infra-private-builds.git#a6b42dabedcf7c724bd36a614ebe9fa99c777e62" dependencies: "@angular/benchpress" "0.2.1" @@ -1236,6 +1235,11 @@ resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== +"@discoveryjs/json-ext@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" + integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== + "@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"