build: emit performance JSON file for each ng_module() (#41125)
A previous commit implemented a streamlined performance metric reporting system for the compiler-cli, controlled via the compiler option `tracePerformance`. This commit adds a custom Bazel flag rule //packages/compiler-cli:ng_perf to the repository, and wires it through to the `ng_module` implementation such that if the flag is set, `ng_module` will produce perf results as part of the build. The underlying mechanism of `//:ng_perf` is not exported from `@angular/bazel` as a public rule that consumers can use, so there is little risk of accidental dependency on the contents of these perf traces. An alias is added so that `--ng_perf` is a Bazel flag which works in our repository. PR Close #41125
This commit is contained in:
parent
48fec08c95
commit
b61c009c54
7
.bazelrc
7
.bazelrc
|
@ -140,6 +140,13 @@ build:remote --remote_executor=remotebuildexecution.googleapis.com
|
|||
# retry mechanism and we do not want to retry unnecessarily if Karma already tried multiple times.
|
||||
test:saucelabs --flaky_test_attempts=1
|
||||
|
||||
################
|
||||
# Flag Aliases #
|
||||
################
|
||||
|
||||
# --ng_perf will ask the Ivy compiler to produce performance results for each build.
|
||||
build --flag_alias=ng_perf=//packages/compiler-cli:ng_perf
|
||||
|
||||
####################################################
|
||||
# User bazel configuration
|
||||
# NOTE: This needs to be the *last* entry in the config.
|
||||
|
|
|
@ -12,5 +12,6 @@ load("//packages/bazel/src:ng_module.bzl", _ng_module = "ng_module_macro")
|
|||
|
||||
ng_module = _ng_module
|
||||
ng_package = _ng_package
|
||||
|
||||
# DO NOT ADD PUBLIC API without including in the documentation generation
|
||||
# Run `yarn bazel build //packages/bazel/docs` to verify
|
||||
|
|
|
@ -26,9 +26,19 @@ load(
|
|||
"tsc_wrapped_tsconfig",
|
||||
)
|
||||
|
||||
# enable_perf_logging controls whether Ivy's performance tracing system will be enabled for any
|
||||
# compilation which includes this provider.
|
||||
NgPerfInfo = provider(fields = ["enable_perf_logging"])
|
||||
|
||||
_FLAT_DTS_FILE_SUFFIX = ".bundle.d.ts"
|
||||
_R3_SYMBOLS_DTS_FILE = "src/r3_symbols.d.ts"
|
||||
|
||||
def is_perf_requested(ctx):
|
||||
enable_perf_logging = ctx.attr.perf_flag != None and ctx.attr.perf_flag[NgPerfInfo].enable_perf_logging == True
|
||||
if enable_perf_logging and not is_ivy_enabled(ctx):
|
||||
fail("Angular View Engine does not support performance tracing")
|
||||
return enable_perf_logging
|
||||
|
||||
def is_ivy_enabled(ctx):
|
||||
"""Determine if the ivy compiler should be used to by the ng_module.
|
||||
|
||||
|
@ -278,6 +288,15 @@ def _expected_outs(ctx):
|
|||
else:
|
||||
i18n_messages_files = []
|
||||
|
||||
dev_perf_files = []
|
||||
prod_perf_files = []
|
||||
|
||||
# In Ivy mode, dev and prod builds both produce a .json output containing performance metrics
|
||||
# from the compiler for that build.
|
||||
if is_perf_requested(ctx):
|
||||
dev_perf_files = [ctx.actions.declare_file(ctx.label.name + "_perf_dev.json")]
|
||||
prod_perf_files = [ctx.actions.declare_file(ctx.label.name + "_perf_prod.json")]
|
||||
|
||||
return struct(
|
||||
closure_js = closure_js_files,
|
||||
devmode_js = devmode_js_files,
|
||||
|
@ -288,6 +307,8 @@ def _expected_outs(ctx):
|
|||
dts_bundles = dts_bundles,
|
||||
bundle_index_typings = bundle_index_typings,
|
||||
i18n_messages = i18n_messages_files,
|
||||
dev_perf_files = dev_perf_files,
|
||||
prod_perf_files = prod_perf_files,
|
||||
)
|
||||
|
||||
# Determines if we need to generate View Engine shims (.ngfactory and .ngsummary files)
|
||||
|
@ -336,6 +357,15 @@ def _ngc_tsconfig(ctx, files, srcs, **kwargs):
|
|||
"_useManifestPathsAsModuleName": (not _is_bazel()),
|
||||
}
|
||||
|
||||
if is_perf_requested(ctx):
|
||||
# In Ivy mode, set the `tracePerformance` Angular compiler option to enable performance
|
||||
# metric output.
|
||||
if "devmode_manifest" in kwargs:
|
||||
perf_path = outs.dev_perf_files[0].path
|
||||
else:
|
||||
perf_path = outs.prod_perf_files[0].path
|
||||
angular_compiler_options["tracePerformance"] = perf_path
|
||||
|
||||
if _should_produce_flat_module_outs(ctx):
|
||||
angular_compiler_options["flatModuleId"] = ctx.attr.module_name
|
||||
angular_compiler_options["flatModuleOutFile"] = _flat_module_out_file(ctx)
|
||||
|
@ -519,6 +549,7 @@ def _compile_action(
|
|||
outputs,
|
||||
dts_bundles_out,
|
||||
messages_out,
|
||||
perf_out,
|
||||
tsconfig_file,
|
||||
node_opts,
|
||||
compile_mode):
|
||||
|
@ -563,12 +594,12 @@ def _compile_action(
|
|||
|
||||
def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
return _compile_action(ctx, inputs, outputs + outs.closure_js, None, outs.i18n_messages, tsconfig_file, node_opts, "prodmode")
|
||||
return _compile_action(ctx, inputs, outputs + outs.closure_js + outs.prod_perf_files, None, outs.i18n_messages, outs.prod_perf_files, tsconfig_file, node_opts, "prodmode")
|
||||
|
||||
def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
compile_action_outputs = outputs + outs.devmode_js + outs.declarations + outs.summaries + outs.metadata
|
||||
_compile_action(ctx, inputs, compile_action_outputs, outs.dts_bundles, None, tsconfig_file, node_opts, "devmode")
|
||||
compile_action_outputs = outputs + outs.devmode_js + outs.declarations + outs.summaries + outs.metadata + outs.dev_perf_files
|
||||
_compile_action(ctx, inputs, compile_action_outputs, outs.dts_bundles, None, outs.dev_perf_files, tsconfig_file, node_opts, "devmode")
|
||||
|
||||
def _ts_expected_outs(ctx, label, srcs_files = []):
|
||||
# rules_typescript expects a function with two or more arguments, but our
|
||||
|
@ -711,6 +742,16 @@ NG_MODULE_ATTRIBUTES = {
|
|||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
# In the angular/angular monorepo, //tools:defaults.bzl wraps the ng_module rule in a macro
|
||||
# which sets this attribute to the //packages/compiler-cli:ng_perf flag.
|
||||
# This is done to avoid exposing the flag to user projects, which would require:
|
||||
# * defining the flag within @angular/bazel and referencing it correctly here, and
|
||||
# * committing to the flag and its semantics (including the format of perf JSON files)
|
||||
# as something users can depend upon.
|
||||
"perf_flag": attr.label(
|
||||
providers = [NgPerfInfo],
|
||||
doc = "Private API to control production of performance metric JSON files",
|
||||
),
|
||||
"_supports_workers": attr.bool(default = True),
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright Google LLC 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
|
||||
|
||||
load(":ng_module.bzl", "NgPerfInfo")
|
||||
|
||||
def _ng_perf_flag_impl(ctx):
|
||||
return NgPerfInfo(enable_perf_logging = ctx.build_setting_value)
|
||||
|
||||
# `ng_perf_flag` is a special `build_setting` rule which ultimately enables a command-line boolean
|
||||
# flag to control whether the `ng_module` rule produces performance tracing JSON files (in Ivy mode)
|
||||
# as declared outputs.
|
||||
#
|
||||
# It does this via the `NgPerfInfo` provider and the `perf_flag` attriubute on `ng_module`. For more
|
||||
# details, see: https://docs.bazel.build/versions/master/skylark/config.html
|
||||
ng_perf_flag = rule(
|
||||
implementation = _ng_perf_flag_impl,
|
||||
build_setting = config.bool(flag = True),
|
||||
)
|
|
@ -2,6 +2,10 @@ package(default_visibility = ["//visibility:public"])
|
|||
|
||||
load("//tools:defaults.bzl", "pkg_npm", "ts_api_guardian_test", "ts_config", "ts_library")
|
||||
|
||||
# Load ng_perf_flag explicitly from ng_perf.bzl as it's private API, and not exposed to other
|
||||
# consumers of @angular/bazel.
|
||||
load("//packages/bazel/src:ng_perf.bzl", "ng_perf_flag")
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig-build.json",
|
||||
|
@ -88,3 +92,9 @@ ts_api_guardian_test(
|
|||
],
|
||||
golden = "angular/goldens/public-api/compiler-cli/compiler_options.d.ts",
|
||||
)
|
||||
|
||||
# Controls whether the Ivy compiler produces performance traces as part of each build
|
||||
ng_perf_flag(
|
||||
name = "ng_perf",
|
||||
build_setting_default = False,
|
||||
)
|
||||
|
|
|
@ -156,6 +156,7 @@ def ng_module(name, tsconfig = None, entry_point = None, testonly = False, deps
|
|||
api_extractor = _INTERNAL_NG_MODULE_API_EXTRACTOR,
|
||||
ng_xi18n = _INTERNAL_NG_MODULE_XI18N,
|
||||
module_name = module_name,
|
||||
perf_flag = "//packages/compiler-cli:ng_perf",
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue