diff --git a/package.json b/package.json
index f70c61f075c..a545b987cc1 100644
--- a/package.json
+++ b/package.json
@@ -73,6 +73,7 @@
"@bazel/rollup": "5.4.1",
"@bazel/runfiles": "5.4.1",
"@bazel/terser": "5.4.1",
+ "@bazel/worker": "5.4.1",
"@microsoft/api-extractor": "7.22.2",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^21.0.0",
diff --git a/packages/bazel/package.json b/packages/bazel/package.json
index cbfa8714dd7..007931c0820 100644
--- a/packages/bazel/package.json
+++ b/packages/bazel/package.json
@@ -30,6 +30,7 @@
"peerDependencies": {
"@angular/compiler-cli": "0.0.0-PLACEHOLDER",
"@bazel/concatjs": "^5.3.0",
+ "@bazel/worker": "^5.3.0",
"@rollup/plugin-commonjs": "^21.0.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"rollup": "^2.56.3",
diff --git a/packages/bazel/src/ng_package/ng_package.bzl b/packages/bazel/src/ng_package/ng_package.bzl
index 93e94de34b6..193ac4fde0f 100644
--- a/packages/bazel/src/ng_package/ng_package.bzl
+++ b/packages/bazel/src/ng_package/ng_package.bzl
@@ -221,7 +221,7 @@ def _run_rollup(ctx, bundle_name, rollup_config, entry_point, inputs, js_output,
if stamp and ctx.version_file:
other_inputs.append(ctx.version_file)
ctx.actions.run(
- progress_message = "ng_package: Rollup %s %s" % (bundle_name, ctx.label),
+ progress_message = "ng_package: Rollup %s (%s)" % (bundle_name, entry_point.short_path),
mnemonic = "AngularPackageRollup",
inputs = inputs.to_list() + other_inputs,
outputs = [js_output, map_output],
diff --git a/packages/bazel/src/types_bundle/BUILD.bazel b/packages/bazel/src/types_bundle/BUILD.bazel
index 761c77abbb9..e08ad5cfecb 100644
--- a/packages/bazel/src/types_bundle/BUILD.bazel
+++ b/packages/bazel/src/types_bundle/BUILD.bazel
@@ -10,6 +10,7 @@ ts_library(
"index.ts",
],
deps = [
+ "@npm//@bazel/worker",
"@npm//@microsoft/api-extractor",
"@npm//@types/node",
],
@@ -17,11 +18,7 @@ ts_library(
nodejs_binary(
name = "types_bundler",
- data = [
- ":lib",
- "@npm//@bazel/concatjs",
- "@npm//@microsoft/api-extractor",
- ],
+ data = [":lib"],
entry_point = ":index.ts",
# Disable the linker and rely on patched resolution which works better on Windows
# and is less prone to race conditions when targets build concurrently.
diff --git a/packages/bazel/src/types_bundle/index.bzl b/packages/bazel/src/types_bundle/index.bzl
index 63ad36b7c07..e52a9dd1fcd 100644
--- a/packages/bazel/src/types_bundle/index.bzl
+++ b/packages/bazel/src/types_bundle/index.bzl
@@ -28,12 +28,19 @@ def bundle_type_declaration(
args.add(license_banner_file.path)
inputs.append(license_banner_file)
+ # Pass arguments using a flag-file prefixed with `@`. This is
+ # a requirement for build action arguments in persistent workers.
+ # https://docs.bazel.build/versions/main/creating-workers.html#work-action-requirements.
+ args.use_param_file("@%s", use_always = True)
+ args.set_param_file_format("multiline")
+
ctx.actions.run(
mnemonic = "BundlingTypes",
inputs = depset(inputs, transitive = [types]),
outputs = [output_file],
executable = ctx.executable._types_bundler_bin,
arguments = [args],
+ execution_requirements = {"supports-workers": "1"},
progress_message = "Bundling types (%s)" % entry_point.short_path,
)
diff --git a/packages/bazel/src/types_bundle/index.ts b/packages/bazel/src/types_bundle/index.ts
index 6703537d49e..28fbb89da74 100644
--- a/packages/bazel/src/types_bundle/index.ts
+++ b/packages/bazel/src/types_bundle/index.ts
@@ -9,7 +9,8 @@
///
///
-import {Extractor, ExtractorConfig, IConfigFile, IExtractorConfigPrepareOptions,} from '@microsoft/api-extractor';
+import {runAsWorker, runWorkerLoop} from '@bazel/worker';
+import {Extractor, ExtractorConfig, ExtractorMessage, IConfigFile, IExtractorConfigPrepareOptions} from '@microsoft/api-extractor';
import * as fs from 'fs';
import * as path from 'path';
@@ -55,7 +56,8 @@ export async function runMain(
};
const extractorConfig = ExtractorConfig.prepare(options);
- const {succeeded} = Extractor.invoke(extractorConfig);
+ const {succeeded} =
+ Extractor.invoke(extractorConfig, {messageCallback: handleApiExtractorMessage});
if (!succeeded) {
throw new Error('Type bundling failed. See error above.');
@@ -89,12 +91,51 @@ function stripAmdModuleDirectiveComments(content: string): string {
return content.replace(/^\/\/\/ [\r\n]+/gm, '');
}
-// Entry point
-const [entryPointExecpath, outputExecpath, packageJsonExecpath, licenseBannerExecpath] =
- process.argv.slice(2);
+/**
+ * Handles logging messages from API extractor.
+ *
+ * Certain info messages should be omitted and other messages should be printed
+ * to stderr to avoid worker protocol conflicts.
+ */
+function handleApiExtractorMessage(msg: ExtractorMessage): void {
+ msg.handled = true;
-runMain({entryPointExecpath, outputExecpath, packageJsonExecpath, licenseBannerExecpath})
- .catch(e => {
- console.error(e);
+ if (msg.messageId === 'console-compiler-version-notice' || msg.messageId === 'console-preamble') {
+ return;
+ }
+
+ if (msg.logLevel !== 'verbose' && msg.logLevel !== 'none') {
+ console.error(msg.text);
+ }
+}
+
+/** Runs one build using the specified build action command line arguments. */
+async function runOneBuild(args: string[]): Promise {
+ const [entryPointExecpath, outputExecpath, packageJsonExecpath, licenseBannerExecpath] = args;
+
+ try {
+ await runMain({entryPointExecpath, outputExecpath, packageJsonExecpath, licenseBannerExecpath});
+ return true;
+ } catch (e) {
+ console.error(e);
+ return false;
+ }
+}
+
+// Entry-point.
+const processArgs = process.argv.slice(2);
+
+if (runAsWorker(processArgs)) {
+ runWorkerLoop(runOneBuild);
+} else {
+ // In non-worker mode we need to manually read the flag file and omit
+ // the leading `@` that is added as part of the worker requirements.
+ const flagFile = processArgs[0].substring(1);
+ const args = fs.readFileSync(flagFile, 'utf8').split('\n');
+
+ runOneBuild(args).then(success => {
+ if (!success) {
process.exitCode = 1;
- });
+ }
+ });
+}