Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(bazel): speed up d.ts bundling by configuring worker #45900

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions packages/bazel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/bazel/src/ng_package/ng_package.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
7 changes: 2 additions & 5 deletions packages/bazel/src/types_bundle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@ ts_library(
"index.ts",
],
deps = [
"@npm//@bazel/worker",
"@npm//@microsoft/api-extractor",
"@npm//@types/node",
],
)

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.
Expand Down
7 changes: 7 additions & 0 deletions packages/bazel/src/types_bundle/index.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)

Expand Down
59 changes: 50 additions & 9 deletions packages/bazel/src/types_bundle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
/// <reference types="node"/>
/// <reference lib="es2020"/>

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';

Expand Down Expand Up @@ -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.');
Expand Down Expand Up @@ -89,12 +91,51 @@ function stripAmdModuleDirectiveComments(content: string): string {
return content.replace(/^\/\/\/ <amd-module name=.*\/>[\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;

if (msg.messageId === 'console-compiler-version-notice' || msg.messageId === 'console-preamble') {
return;
}

if (msg.logLevel !== 'verbose' && msg.logLevel !== 'none') {
console.error(msg.text);
}
}

runMain({entryPointExecpath, outputExecpath, packageJsonExecpath, licenseBannerExecpath})
.catch(e => {
console.error(e);
/** Runs one build using the specified build action command line arguments. */
async function runOneBuild(args: string[]): Promise<boolean> {
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;
});
}
});
}