diff --git a/dev-infra/bazel/BUILD.bazel b/dev-infra/bazel/BUILD.bazel new file mode 100644 index 0000000000..ffd0fb0cdc --- /dev/null +++ b/dev-infra/bazel/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/dev-infra/bazel/expand_template.bzl b/dev-infra/bazel/expand_template.bzl new file mode 100644 index 0000000000..e21bd9fa1d --- /dev/null +++ b/dev-infra/bazel/expand_template.bzl @@ -0,0 +1,45 @@ +"""Implementation of the expand_template rule """ + +def expand_template_impl(ctx): + substitutions = dict() + + for k in ctx.attr.configuration_env_vars: + if k in ctx.var.keys(): + substitutions["TMPL_%s" % k] = ctx.var[k] + + for k in ctx.attr.substitutions: + substitutions[k] = ctx.expand_location(ctx.attr.substitutions[k], targets = ctx.attr.data) + + ctx.actions.expand_template( + template = ctx.file.template, + output = ctx.outputs.output_name, + substitutions = substitutions, + ) + +"""Rule that can be used to substitute variables in a given template file.""" +expand_template = rule( + implementation = expand_template_impl, + attrs = { + "configuration_env_vars": attr.string_list( + default = [], + doc = "Bazel configuration variables which should be exposed to the template.", + ), + "output_name": attr.output( + mandatory = True, + doc = "File where the substituted template is written to.", + ), + "substitutions": attr.string_dict( + mandatory = True, + doc = "Dictionary of substitutions that should be available to the template. Dictionary key represents the placeholder in the template.", + ), + "data": attr.label_list( + doc = """Data dependencies for location expansion.""", + allow_files = True, + ), + "template": attr.label( + mandatory = True, + allow_single_file = True, + doc = "File used as template.", + ), + }, +) diff --git a/dev-infra/benchmark/component_benchmark/component_benchmark.bzl b/dev-infra/benchmark/component_benchmark/component_benchmark.bzl index 9394cdd69a..edf4d0f4e0 100644 --- a/dev-infra/benchmark/component_benchmark/component_benchmark.bzl +++ b/dev-infra/benchmark/component_benchmark/component_benchmark.bzl @@ -132,7 +132,7 @@ def component_benchmark( bootstrap = ["//packages/zone.js/bundles:zone.umd.js"], port = 4200, static_files = assets + styles, - deps = [":" + app_main + ".min_debug.es2015.js"], + deps = [":" + app_main + ".min_debug.js"], additional_root_paths = ["//dev-infra/benchmark/component_benchmark/defaults"], serving_path = "/app_bundle.js", ) diff --git a/dev-infra/benchmark/ng_rollup_bundle/BUILD.bazel b/dev-infra/benchmark/ng_rollup_bundle/BUILD.bazel index 0b7900ba98..afb8a7a695 100644 --- a/dev-infra/benchmark/ng_rollup_bundle/BUILD.bazel +++ b/dev-infra/benchmark/ng_rollup_bundle/BUILD.bazel @@ -3,7 +3,7 @@ package(default_visibility = ["//visibility:public"]) load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary") exports_files([ - "rollup.config.js", + "rollup.config-tmpl.js", "terser_config.json", ]) diff --git a/dev-infra/benchmark/ng_rollup_bundle/ng_rollup_bundle.bzl b/dev-infra/benchmark/ng_rollup_bundle/ng_rollup_bundle.bzl index c478ce3df0..a7eb00e66f 100644 --- a/dev-infra/benchmark/ng_rollup_bundle/ng_rollup_bundle.bzl +++ b/dev-infra/benchmark/ng_rollup_bundle/ng_rollup_bundle.bzl @@ -3,414 +3,90 @@ # 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 -"""Rollup with Build Optimizer - - This provides a variant of the [rollup_bundle] rule that works better for Angular apps. - - It registers `@angular-devkit/build-optimizer` as a rollup plugin, to get - better optimization. It also uses ESM5 format inputs, as this is what - build-optimizer is hard-coded to look for and transform. - - [rollup_bundle]: https://bazelbuild.github.io/rules_nodejs/rollup/rollup_bundle.html -""" - load("@build_bazel_rules_nodejs//:index.bzl", "npm_package_bin") -load("@build_bazel_rules_nodejs//:providers.bzl", "JSEcmaScriptModuleInfo", "NpmPackageInfo", "node_modules_aspect") -load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "esm5_root_dir", "flatten_esm5") load("@npm_bazel_terser//:index.bzl", "terser_minified") +load("@npm_bazel_rollup//:index.bzl", "rollup_bundle") +load("//dev-infra/bazel:expand_template.bzl", "expand_template") -_NG_ROLLUP_BUNDLE_OUTPUTS = { - "bundle": "%{name}.js", - "sourcemap": "%{name}.js.map", -} +def ng_rollup_bundle( + name, + entry_point, + deps = [], + license_banner = None, + build_optimizer = True, + visibility = None, + format = "iife", + globals = {}, + **kwargs): + """Rollup with Build Optimizer on target prodmode output (ESM2015). -_NG_ROLLUP_MODULE_MAPPINGS_ATTR = "ng_rollup_module_mappings" - -def _ng_rollup_module_mappings_aspect_impl(target, ctx): - mappings = dict() - for dep in ctx.rule.attr.deps: - if hasattr(dep, _NG_ROLLUP_MODULE_MAPPINGS_ATTR): - for k, v in getattr(dep, _NG_ROLLUP_MODULE_MAPPINGS_ATTR).items(): - if k in mappings and mappings[k] != v: - fail(("duplicate module mapping at %s: %s maps to both %s and %s" % - (target.label, k, mappings[k], v)), "deps") - mappings[k] = v - if ((hasattr(ctx.rule.attr, "module_name") and ctx.rule.attr.module_name) or - (hasattr(ctx.rule.attr, "module_root") and ctx.rule.attr.module_root)): - mn = ctx.rule.attr.module_name - if not mn: - mn = target.label.name - mr = target.label.package - if target.label.workspace_root: - mr = "%s/%s" % (target.label.workspace_root, mr) - if ctx.rule.attr.module_root and ctx.rule.attr.module_root != ".": - if ctx.rule.attr.module_root.endswith(".ts"): - # This is the type-checking module mapping. Strip the trailing .d.ts - # as it doesn't belong in TypeScript's path mapping. - mr = "%s/%s" % (mr, ctx.rule.attr.module_root.replace(".d.ts", "")) - else: - mr = "%s/%s" % (mr, ctx.rule.attr.module_root) - if mn in mappings and mappings[mn] != mr: - fail(("duplicate module mapping at %s: %s maps to both %s and %s" % - (target.label, mn, mappings[mn], mr)), "deps") - mappings[mn] = mr - return struct(ng_rollup_module_mappings = mappings) - -ng_rollup_module_mappings_aspect = aspect( - _ng_rollup_module_mappings_aspect_impl, - attr_aspects = ["deps"], -) - -_NG_ROLLUP_BUNDLE_DEPS_ASPECTS = [esm5_outputs_aspect, ng_rollup_module_mappings_aspect, node_modules_aspect] - -_NG_ROLLUP_BUNDLE_ATTRS = { - "build_optimizer": attr.bool( - doc = """Use build optimizer plugin - - Only used if sources are esm5 which depends on value of esm5_sources.""", - default = True, - ), - "esm5_sources": attr.bool( - doc = """Use esm5 input sources""", - default = True, - ), - "srcs": attr.label_list( - doc = """JavaScript source files from the workspace. - These can use ES2015 syntax and ES Modules (import/export)""", - allow_files = True, - ), - "entry_point": attr.label( - doc = """The starting point of the application, passed as the `--input` flag to rollup. - - If the entry JavaScript file belongs to the same package (as the BUILD file), - you can simply reference it by its relative name to the package directory: - - ``` - ng_rollup_bundle( - name = "bundle", - entry_point = ":main.js", - ) - ``` - - You can specify the entry point as a typescript file so long as you also include - the ts_library target in deps: - - ``` - ts_library( - name = "main", - srcs = ["main.ts"], - ) - - ng_rollup_bundle( - name = "bundle", - deps = [":main"] - entry_point = ":main.ts", - ) - ``` - - The rule will use the corresponding `.js` output of the ts_library rule as the entry point. - - If the entry point target is a rule, it should produce a single JavaScript entry file that will be passed to the nodejs_binary rule. - For example: - - ``` - filegroup( - name = "entry_file", - srcs = ["main.js"], - ) - - ng_rollup_bundle( - name = "bundle", - entry_point = ":entry_file", - ) - ``` - """, - mandatory = True, - allow_single_file = True, - ), - "deps": attr.label_list( - doc = """Other targets that provide JavaScript files. - Typically this will be `ts_library` or `ng_module` targets.""", - aspects = _NG_ROLLUP_BUNDLE_DEPS_ASPECTS, - ), - "format": attr.string( - doc = """"Specifies the format of the generated bundle. One of the following: - -- `amd`: Asynchronous Module Definition, used with module loaders like RequireJS -- `cjs`: CommonJS, suitable for Node and other bundlers -- `esm`: Keep the bundle as an ES module file, suitable for other bundlers and inclusion as a `