Skip to content

Commit f74bd1b

Browse files
devversionalxhub
authored andcommitted
perf(bazel): reduce input files for ng_package rollup and type bundle actions (#46187)
We currently use all the ESM2020 and type sources as inputs for rollup and type bundle actions, respectively. This is a source of slowness in Bazel sandboxed builds because many unused files will be linked/made available for many concurrently-running actions. We should limit the inputs only to what is assumed to be used. We cannot know exactly and need to include transitive types from `node_modules`, but that is an inevitable construct with the current Bazel rules. Note that the external node modules could still bring in a lot of files, like in Material where the `.d.ts` files for all locales are brought into the sandbox (from `@angular/common`). We likely would need to remove these files in a postinstall for now, to speed up actions, similar to how we did it for RxJS in all repositories. These are known to be not used in the components repo. PR Close #46187
1 parent c26b6d9 commit f74bd1b

File tree

1 file changed

+27
-26
lines changed

1 file changed

+27
-26
lines changed

packages/bazel/src/ng_package/ng_package.bzl

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,9 @@ def _ng_package_impl(ctx):
301301
fesm2015 = []
302302
type_files = []
303303

304-
# We collect all ESM2020 source
305-
unscoped_esm2020_depsets = []
306-
unscoped_type_definition_depsets = []
304+
# List of unscoped direct and transitive ESM sources that are provided
305+
# by all entry-points.
306+
unscoped_all_entry_point_esm2020 = []
307307

308308
# We infer the entry points to be:
309309
# - ng_module rules in the deps (they have an "angular" provider)
@@ -319,23 +319,6 @@ def _ng_package_impl(ctx):
319319
if not dep.label.package.startswith(owning_package):
320320
fail("Unexpected dependency. %s is defined outside of %s." % (dep, owning_package))
321321

322-
# Collect ESM2020 source files from the dependency, including transitive sources which
323-
# are not directly defined in the entry-point. This is necessary to allow for
324-
# entry-points to rely on sub-targets (which can be done for incrementality).
325-
if JSEcmaScriptModuleInfo in dep:
326-
unscoped_esm2020_depsets.append(dep[JSEcmaScriptModuleInfo].sources)
327-
328-
# Collect the type definitions files for the entry-point.
329-
if DeclarationInfo in dep:
330-
unscoped_type_definition_depsets.append(dep[DeclarationInfo].transitive_declarations)
331-
332-
# Note: Using `to_list()` is expensive but we cannot get around this here as
333-
# we need to filter out generated files and need to be able to iterate through
334-
# JavaScript and typing files in order to detect entry-point index and typing files.
335-
unscoped_esm2020 = depset(transitive = unscoped_esm2020_depsets).to_list()
336-
unscoped_type_definitions = depset(transitive = unscoped_type_definition_depsets).to_list()
337-
338-
for dep in ctx.attr.deps:
339322
# Module name of the current entry-point. eg. @angular/core/testing
340323
module_name = ""
341324

@@ -348,6 +331,19 @@ def _ng_package_impl(ctx):
348331
# Whether this dependency is for the primary entry-point of the package.
349332
is_primary_entry_point = entry_point == ""
350333

334+
# Collect ESM2020 and type definition source files from the dependency, including
335+
# transitive sources which are not directly defined in the entry-point. This is
336+
# necessary to allow for entry-points to rely on sub-targets (as a perf improvement).
337+
unscoped_esm2020_depset = dep[JSEcmaScriptModuleInfo].sources
338+
unscoped_types_depset = dep[DeclarationInfo].transitive_declarations
339+
340+
# Note: Using `to_list()` is expensive but we cannot get around this here as
341+
# we need to filter out generated files and need to be able to iterate through
342+
# JavaScript files in order to capture the `esm2020/` in the APF, and to be able
343+
# to detect entry-point index files when no flat module metadata is available.
344+
unscoped_esm2020 = unscoped_esm2020_depset.to_list()
345+
unscoped_all_entry_point_esm2020.extend(unscoped_esm2020)
346+
351347
# Extract the "module_name" from either "ts_library" or "ng_module". Both
352348
# set the "module_name" in the provider struct.
353349
if hasattr(dep, "module_name"):
@@ -379,11 +375,16 @@ def _ng_package_impl(ctx):
379375
"guessing `index.mjs` as main file of the entry-point",
380376
)
381377

378+
# Note: Using `to_list()` is expensive but we cannot get around this here as
379+
# we need to filter out generated files and need to be able to iterate through
380+
# typing files in order to determine the entry-point type file.
381+
unscoped_types = unscoped_types_depset.to_list()
382+
382383
# In case the dependency is built through the "ts_library" rule, or the "ng_module"
383384
# rule does not generate a flat module bundle, we determine the index file and
384385
# typings entry-point through the most reasonable defaults (i.e. "package/index").
385386
es2020_entry_point = _find_matching_file(unscoped_esm2020, "%s/index.mjs" % entry_point_package)
386-
typings_entry_point = _find_matching_file(unscoped_type_definitions, "%s/index.d.ts" % entry_point_package)
387+
typings_entry_point = _find_matching_file(unscoped_types, "%s/index.d.ts" % entry_point_package)
387388
guessed_paths = True
388389

389390
bundle_name = "%s.mjs" % (primary_bundle_name if is_primary_entry_point else entry_point)
@@ -408,7 +409,7 @@ def _ng_package_impl(ctx):
408409
output_file = typings_file,
409410
entry_point = typings_entry_point,
410411
license_banner_file = ctx.file.license_banner,
411-
types = depset(transitive = unscoped_type_definition_depsets),
412+
types = unscoped_types_depset,
412413
)
413414

414415
type_files.append(typings_file)
@@ -426,8 +427,8 @@ def _ng_package_impl(ctx):
426427

427428
# Note: For creating the bundles, we use all the ESM2020 sources that have been
428429
# collected from the dependencies. This allows for bundling of code that is not
429-
# necessarily part of the owning package (using the `externals` attribute)
430-
rollup_inputs = depset(unscoped_esm2020)
430+
# necessarily part of the owning package (with respect to the `externals` attribute)
431+
rollup_inputs = unscoped_esm2020_depset
431432
esm2020_config = _write_rollup_config(ctx, ctx.bin_dir.path, filename = "_%s.rollup_esm2020.conf.js")
432433
esm2015_config = _write_rollup_config(ctx, ctx.bin_dir.path, filename = "_%s.rollup_esm2015.conf.js", downlevel_to_es2015 = True)
433434

@@ -457,7 +458,7 @@ def _ng_package_impl(ctx):
457458

458459
# Filter ESM2020 JavaScript inputs to files which are part of the owning package. The
459460
# packager should not copy external files into the package.
460-
esm2020 = _filter_esm_files_to_include(unscoped_esm2020, owning_package)
461+
esm2020 = _filter_esm_files_to_include(unscoped_all_entry_point_esm2020, owning_package)
461462

462463
packager_inputs = (
463464
static_files +
@@ -566,7 +567,7 @@ _NG_PACKAGE_ATTRS = dict(PKG_NPM_ATTRS, **{
566567
"deps": attr.label_list(
567568
doc = """ Targets that produce production JavaScript outputs, such as `ts_library`.""",
568569
aspects = _NG_PACKAGE_DEPS_ASPECTS,
569-
providers = [JSEcmaScriptModuleInfo],
570+
providers = [JSEcmaScriptModuleInfo, DeclarationInfo],
570571
cfg = partial_compilation_transition,
571572
),
572573
"readme_md": attr.label(allow_single_file = [".md"]),

0 commit comments

Comments
 (0)