豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit a3f061f

Browse files
committed
feat(bazel): expose individual .map files for optimized bundles
Currently we do not declare individual file targets/pre-declared outputs for map files, but we do for `.js` files. This is inconsistent and the individual `map` files are useful to be "reference-able" when e.g. a JS mapping size test is configured. To achieve this we introduce a new rule for filtering outputs. This rule will become helpful in the future as we often have scenarios where `$(rootpath X)` cannot be used due to multiple outputs, even though e.g. a genrule might only be interested in a single file for constructing a command.
1 parent faed1ba commit a3f061f

File tree

6 files changed

+82
-5
lines changed

6 files changed

+82
-5
lines changed

bazel/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ filegroup(
55
"expand_template.bzl",
66
"extract_js_module_output.bzl",
77
"extract_types.bzl",
8+
"filter_outputs.bzl",
89
"//bazel/api-golden:files",
910
"//bazel/app-bundling:files",
1011
"//bazel/benchmark:files",
@@ -15,6 +16,7 @@ filegroup(
1516
"//bazel/integration:files",
1617
"//bazel/karma:files",
1718
"//bazel/map-size-tracking:files",
19+
"//bazel/private:files",
1820
"//bazel/remote-execution:files",
1921
"//bazel/spec-bundling:files",
2022
],

bazel/app-bundling/index.bzl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ load("@npm//@bazel/terser:index.bzl", "terser_minified")
88
load("@npm//prettier:index.bzl", "prettier")
99
load("//bazel/esbuild:index.bzl", "esbuild", "esbuild_config")
1010
load("//bazel:expand_template.bzl", "expand_template")
11+
load("//bazel:filter_outputs.bzl", "filter_outputs")
1112

1213
def _create_esbuild_minify_options(debug = False):
1314
# The minify options match with the configuration used by the CLI. The whitespace
@@ -76,9 +77,7 @@ def app_bundle(
7677
common_terser_options = {
7778
"visibility": visibility,
7879
"config_file": "//bazel/app-bundling:terser_config.json",
79-
# TODO: Enable source maps for better debugging when `@bazel/terser` pre-declares
80-
# JS and map outputs. Tracked with: DEV-120
81-
"sourcemap": False,
80+
"sourcemap": True,
8281
}
8382

8483
esbuild(
@@ -94,10 +93,12 @@ def app_bundle(
9493
)
9594

9695
terser_minified(name = name + ".min", src = name + ".js", **common_terser_options)
97-
native.filegroup(name = name + ".min.js", srcs = [name + ".min"], visibility = visibility)
96+
filter_outputs(name = name + ".min.js", target = ":%s.min" % name, filters = ["%s.min.js" % name], visibility = visibility)
97+
filter_outputs(name = name + ".min.js.map", target = ":%s.min" % name, filters = ["%s.min.js.map" % name], visibility = visibility)
9898

9999
terser_minified(name = name + ".debug.min", src = name + ".debug.js", debug = True, tags = ["manual"], **common_terser_options)
100-
native.filegroup(name = name + ".debug.min.js", srcs = [name + ".debug.min"], visibility = visibility, tags = ["manual"])
100+
filter_outputs(name = name + ".debug.min.js", target = ":%s.debug.min" % name, filters = ["%s.debug.min.js" % name], visibility = visibility)
101+
filter_outputs(name = name + ".debug.min.js.map", target = ":%s.debug.min" % name, filters = ["%s.debug.min.js.map" % name], visibility = visibility)
101102

102103
# For better debugging, we also run prettier on the minified debug bundle. This is
103104
# necessary as Terser no longer has beautify/formatting functionality.

bazel/app-bundling/test/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ jasmine_node_test(
3636
name = "test",
3737
data = [
3838
":bundle.min.js",
39+
":bundle.min.js.map",
3940
"@npm//jsdom",
4041
],
4142
# JSDOM should not be bundled because it has workers and dynamic imports.

bazel/filter_outputs.bzl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
load("//bazel/private:manifest_path.bzl", "get_manifest_path")
2+
3+
def _filter_outputs_impl(ctx):
4+
outputs = []
5+
target_label = ctx.attr.target.label
6+
target_workspace = target_label.workspace_name if target_label.workspace_name else ctx.workspace_name
7+
target_package_manifest_path = "%s/%s" % (target_workspace, target_label.package)
8+
used_filters = dict()
9+
10+
for output in ctx.attr.target[DefaultInfo].files.to_list():
11+
manifest_path = get_manifest_path(ctx, output)
12+
relative_path = manifest_path[len(target_package_manifest_path) + 1:]
13+
14+
for filter in ctx.attr.filters:
15+
if filter == relative_path:
16+
used_filters[filter] = True
17+
outputs.append(output)
18+
19+
# If some filters are unused, we report an error as we expect every filter to\
20+
# be matched at least once.
21+
if len(used_filters) != len(ctx.attr.filters):
22+
unused_filters = [f for f in ctx.attr.filters if not used_filters.get(f)]
23+
fail("Some filters in `%s` do not match. Unused filters: %s" % (ctx.label, unused_filters))
24+
25+
return [DefaultInfo(files = depset(outputs))]
26+
27+
filter_outputs = rule(
28+
implementation = _filter_outputs_impl,
29+
attrs = {
30+
"target": attr.label(
31+
mandatory = True,
32+
doc = "Target for which outputs should be filtered",
33+
providers = [DefaultInfo],
34+
),
35+
"filters": attr.string_list(
36+
mandatory = True,
37+
doc = """Outputs to filter from the target. Each filter is expected to match
38+
at least once. Filter paths are expected to be relative to the package owning the target.
39+
""",
40+
),
41+
},
42+
doc = """Rule that can be used to filter outputs from a given target.
43+
This is useful when a target exposes multiple output files but a single output is only needed.
44+
""",
45+
)

bazel/private/BUILD.bazel

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package(default_visibility = ["//visibility:public"])
2+
3+
# Make source files available for distribution via pkg_npm
4+
filegroup(
5+
name = "files",
6+
srcs = glob(["*"]),
7+
)

bazel/private/manifest_path.bzl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""Starlark helpers for Bazel manifest paths."""
2+
3+
def get_manifest_path(ctx, file):
4+
"""Computes the manifest path for the given `File`.
5+
6+
For example: `../some/file` becomes `<wksp_name>/some/file` or
7+
`../external_wksp/some/file` becomes `external_wksp/some/file`.
8+
9+
Args:
10+
ctx: Rule context
11+
file: File for which to retrieve the manifest path.
12+
Returns:
13+
A manifest path for the given file.
14+
"""
15+
16+
# If a short path starts with `../`, then the file is from an external
17+
# workspace and we can just strip off the leading segment.
18+
if file.short_path.startswith("../"):
19+
return file.short_path[3:]
20+
21+
return "%s/%s" % (ctx.workspace_name, file.short_path)

0 commit comments

Comments
 (0)