Skip to content

Commit

Permalink
feat(bazel): change ng_package rule to APF v6 (#22782)
Browse files Browse the repository at this point in the history
Angular Package Format v6 stops bundling files in the esm5 and esm2015
directories, now that Webpack 4 can tree-shake per-file.

Adds some missing files like package.json to make packages closer to
what we publish today.

Refactor ng_package to be a type of npm_package and re-use the packaging
action from that rule.

PR Close #22782
  • Loading branch information
alexeagle authored and mhevery committed Mar 15, 2018
1 parent 6e5e819 commit 88b3198
Show file tree
Hide file tree
Showing 42 changed files with 335 additions and 138 deletions.
6 changes: 3 additions & 3 deletions WORKSPACE
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ workspace(name = "angular")


http_archive( http_archive(
name = "build_bazel_rules_nodejs", name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/f03c8b5df155da2a640b6775afdd4fe4aa6fec72.zip", url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.3.zip",
strip_prefix = "rules_nodejs-f03c8b5df155da2a640b6775afdd4fe4aa6fec72", strip_prefix = "rules_nodejs-0.5.3",
sha256 = "9d541f49af8cf60c73efb102186bfa5670ee190a088ce52638dcdf90cd9e2de6", sha256 = "17a5515f59777b00cb25dbc710017a14273f825029b2ec60e0969d28914870be",
) )


load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories") load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories")
Expand Down
6 changes: 3 additions & 3 deletions integration/bazel/WORKSPACE
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ workspace(name = "bazel_integration_test")


http_archive( http_archive(
name = "build_bazel_rules_nodejs", name = "build_bazel_rules_nodejs",
url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.0.zip", url = "https://github.com/bazelbuild/rules_nodejs/archive/0.5.3.zip",
strip_prefix = "rules_nodejs-0.5.0", strip_prefix = "rules_nodejs-0.5.3",
sha256 = "06aabb253c3867d51724386ac5622a0a238bbd82e2c70ce1d09ee3ceac4c31d6", sha256 = "17a5515f59777b00cb25dbc710017a14273f825029b2ec60e0969d28914870be",
) )


load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories") load("@build_bazel_rules_nodejs//:defs.bzl", "node_repositories")
Expand Down
6 changes: 5 additions & 1 deletion packages/animations/BUILD.bazel
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ ng_module(


ng_package( ng_package(
name = "npm_package", name = "npm_package",
srcs = ["package.json"], srcs = [
"package.json",
"//packages/animations/browser:package.json",
"//packages/animations/browser/testing:package.json",
],
entry_point = "packages/animations/index.js", entry_point = "packages/animations/index.js",
secondary_entry_points = [ secondary_entry_points = [
"browser", "browser",
Expand Down
2 changes: 2 additions & 0 deletions packages/animations/browser/BUILD.bazel
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"]) package(default_visibility = ["//visibility:public"])


exports_files(["package.json"])

load("//tools:defaults.bzl", "ng_module") load("//tools:defaults.bzl", "ng_module")


ng_module( ng_module(
Expand Down
2 changes: 2 additions & 0 deletions packages/animations/browser/testing/BUILD.bazel
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,7 @@
package(default_visibility = ["//visibility:public"]) package(default_visibility = ["//visibility:public"])


exports_files(["package.json"])

load("//tools:defaults.bzl", "ng_module") load("//tools:defaults.bzl", "ng_module")


ng_module( ng_module(
Expand Down
4 changes: 2 additions & 2 deletions packages/bazel/BUILD.bazel
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@build_bazel_rules_nodejs//:defs.bzl", "npm_package") load("//tools:defaults.bzl", "npm_package")


genrule( genrule(
name = "workspace", name = "workspace",
Expand All @@ -9,6 +9,7 @@ genrule(
npm_package( npm_package(
name = "npm_package", name = "npm_package",
srcs = [ srcs = [
"BUILD.bazel",
"index.bzl", "index.bzl",
"package.json", "package.json",
"//packages/bazel/src:package_assets", "//packages/bazel/src:package_assets",
Expand All @@ -18,6 +19,5 @@ npm_package(
"//packages/bazel/": "//", "//packages/bazel/": "//",
"angular/packages/bazel/": "angular/", "angular/packages/bazel/": "angular/",
}, },
stamp_data = "//tools:stamp_data",
deps = [":workspace"], deps = [":workspace"],
) )
3 changes: 3 additions & 0 deletions packages/bazel/package.json
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/angular/angular.git" "url": "https://github.com/angular/angular.git"
},
"ng-update": {
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
} }
} }
1 change: 1 addition & 0 deletions packages/bazel/src/esm5.bzl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def _esm5_outputs_aspect(target, ctx):
arguments = [tsconfig.path], arguments = [tsconfig.path],
executable = target.typescript.replay_params.compiler, executable = target.typescript.replay_params.compiler,
execution_requirements = { execution_requirements = {
# TODO(alexeagle): enable worker mode for these compilations
"supports-workers": "0", "supports-workers": "0",
}, },
) )
Expand Down
3 changes: 2 additions & 1 deletion packages/bazel/src/ng_module.bzl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ def _write_bundle_index(ctx):
tsconfig_file = ctx.actions.declare_file("%s.tsconfig.json" % basename) tsconfig_file = ctx.actions.declare_file("%s.tsconfig.json" % basename)
metadata_file = ctx.actions.declare_file("%s.metadata.json" % basename) metadata_file = ctx.actions.declare_file("%s.metadata.json" % basename)
tstyping_file = ctx.actions.declare_file("%s.d.ts" % basename) tstyping_file = ctx.actions.declare_file("%s.d.ts" % basename)
js_file = ctx.actions.declare_file("%s.js" % basename)


tsconfig = dict(tsc_wrapped_tsconfig(ctx, ctx.files.srcs, ctx.files.srcs), **{ tsconfig = dict(tsc_wrapped_tsconfig(ctx, ctx.files.srcs, ctx.files.srcs), **{
"angularCompilerOptions": { "angularCompilerOptions": {
Expand All @@ -271,7 +272,7 @@ def _write_bundle_index(ctx):


ctx.actions.write(tsconfig_file, json_marshal(tsconfig)) ctx.actions.write(tsconfig_file, json_marshal(tsconfig))


outputs = [metadata_file, tstyping_file] outputs = [metadata_file, tstyping_file, js_file]


ctx.action( ctx.action(
progress_message = "Producing metadata for bundle %s" % ctx.label.name, progress_message = "Producing metadata for bundle %s" % ctx.label.name,
Expand Down
83 changes: 60 additions & 23 deletions packages/bazel/src/ng_package/ng_package.bzl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ load("@build_bazel_rules_nodejs//:internal/rollup/rollup_bundle.bzl",
"rollup_module_mappings_aspect", "rollup_module_mappings_aspect",
"run_uglify", "run_uglify",
"ROLLUP_ATTRS") "ROLLUP_ATTRS")
load("@build_bazel_rules_nodejs//:internal/npm_package/npm_package.bzl",
"NPM_PACKAGE_ATTRS",
"NPM_PACKAGE_OUTPUTS",
"create_package")
load("@build_bazel_rules_nodejs//:internal/node.bzl", "sources_aspect")
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "ESM5Info") load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "ESM5Info")


# TODO(alexeagle): this list is incomplete, add more as material ramps up # TODO(alexeagle): this list is incomplete, add more as material ramps up
Expand Down Expand Up @@ -198,10 +203,10 @@ def _rollup(ctx, rollup_config, entry_point, inputs, js_output, format = "es"):
args.add(externals, join_with=",") args.add(externals, join_with=",")


other_inputs = [ctx.executable._rollup, rollup_config] other_inputs = [ctx.executable._rollup, rollup_config]
if ctx.file.stamp_data:
other_inputs.append(ctx.file.stamp_data)
if ctx.file.license_banner: if ctx.file.license_banner:
other_inputs.append(ctx.file.license_banner) other_inputs.append(ctx.file.license_banner)
if ctx.file.stamp_data:
other_inputs.append(ctx.file.stamp_data)
ctx.actions.run( ctx.actions.run(
progress_message = "Angular Packaging: rolling up %s" % ctx.label.name, progress_message = "Angular Packaging: rolling up %s" % ctx.label.name,
mnemonic = "AngularPackageRollup", mnemonic = "AngularPackageRollup",
Expand All @@ -220,12 +225,14 @@ def _rollup(ctx, rollup_config, entry_point, inputs, js_output, format = "es"):
def _flatten_paths(directory): def _flatten_paths(directory):
result = [] result = []
for f in directory: for f in directory:
result.extend([f.js.path, f.map.path]) result.append(f.js.path)
if f.map:
result.append(f.map.path)
return result return result


# ng_package produces package that is npm-ready. # ng_package produces package that is npm-ready.
def _ng_package_impl(ctx): def _ng_package_impl(ctx):
npm_package_directory = ctx.actions.declare_directory(ctx.label.name) npm_package_directory = ctx.actions.declare_directory("%s.ng_pkg" % ctx.label.name)


esm_2015_files = collect_es6_sources(ctx) esm_2015_files = collect_es6_sources(ctx)


Expand All @@ -248,6 +255,15 @@ def _ng_package_impl(ctx):
esm5 = [] esm5 = []
bundles = [] bundles = []


# For Angular Package Format v6, we put all the individual .js files in the
# esm5/ and esm2015/ folders.
for f in esm5_sources.to_list():
if f.path.endswith(".js"):
esm5.append(struct(js = f, map = None))
for f in esm_2015_files.to_list():
if f.path.endswith(".js"):
esm2015.append(struct(js = f, map = None))

for entry_point in [""] + ctx.attr.secondary_entry_points: for entry_point in [""] + ctx.attr.secondary_entry_points:
es2015_entry_point = "/".join([p for p in [ es2015_entry_point = "/".join([p for p in [
ctx.bin_dir.path, ctx.bin_dir.path,
Expand Down Expand Up @@ -279,8 +295,12 @@ def _ng_package_impl(ctx):
min_output = ctx.outputs.umd_min min_output = ctx.outputs.umd_min


config = write_rollup_config(ctx, [], root_dirs) config = write_rollup_config(ctx, [], root_dirs)
esm2015.append(_rollup(ctx, config, es2015_entry_point, esm_2015_files, fesm2015_output))
esm5.append(_rollup(ctx, config, es5_entry_point, esm5_sources, fesm5_output)) # Currently we don't include these rollup "FESM" files in the package.
# They are only accessible as named outputs from the rule.
_rollup(ctx, config, es2015_entry_point, esm_2015_files, fesm2015_output)
_rollup(ctx, config, es5_entry_point, esm5_sources, fesm5_output)

bundles.append(_rollup(ctx, config, es5_entry_point, esm5_sources, umd_output, format = "umd")) bundles.append(_rollup(ctx, config, es5_entry_point, esm5_sources, umd_output, format = "umd"))
uglify_sourcemap = run_uglify(ctx, umd_output, min_output, uglify_sourcemap = run_uglify(ctx, umd_output, min_output,
config_name = entry_point.replace("/", "_")) config_name = entry_point.replace("/", "_"))
Expand All @@ -294,20 +314,19 @@ def _ng_package_impl(ctx):
args.use_param_file("%s", use_always = True) args.use_param_file("%s", use_always = True)
args.add(npm_package_directory.path) args.add(npm_package_directory.path)
args.add(ctx.label.package) args.add(ctx.label.package)
args.add(primary_entry_point_name(ctx.attr.name, ctx.attr.entry_point))
args.add(ctx.attr.secondary_entry_points, join_with=",")
args.add([ctx.bin_dir.path, ctx.label.package], join_with="/") args.add([ctx.bin_dir.path, ctx.label.package], join_with="/")
args.add(ctx.file.readme_md.path if ctx.file.readme_md else "") args.add(ctx.file.readme_md.path if ctx.file.readme_md else "")
args.add(_flatten_paths(esm2015), join_with=",") args.add(_flatten_paths(esm2015), join_with=",")
args.add(_flatten_paths(esm5), join_with=",") args.add(_flatten_paths(esm5), join_with=",")
args.add(_flatten_paths(bundles), join_with=",") args.add(_flatten_paths(bundles), join_with=",")
args.add([s.path for s in ctx.files.srcs], join_with=",") args.add([s.path for s in ctx.files.srcs], join_with=",")
args.add(ctx.file.stamp_data.path if ctx.file.stamp_data else "")
args.add(ctx.file.license_banner.path if ctx.file.license_banner else "") args.add(ctx.file.license_banner.path if ctx.file.license_banner else "")


other_inputs = (metadata_files.to_list() + other_inputs = (metadata_files.to_list() +
[f.js for f in esm2015 + esm5 + bundles] + [f.js for f in esm2015 + esm5 + bundles] +
[f.map for f in esm2015 + esm5 + bundles]) [f.map for f in esm2015 + esm5 + bundles if f.map])
if ctx.file.stamp_data:
other_inputs.append(ctx.file.stamp_data)
if ctx.file.readme_md: if ctx.file.readme_md:
other_inputs.append(ctx.file.readme_md) other_inputs.append(ctx.file.readme_md)
if ctx.file.license_banner: if ctx.file.license_banner:
Expand All @@ -323,24 +342,32 @@ def _ng_package_impl(ctx):
ctx.files.srcs + ctx.files.srcs +
other_inputs, other_inputs,
outputs = [npm_package_directory], outputs = [npm_package_directory],
executable = ctx.executable._packager, executable = ctx.executable._ng_packager,
arguments = [args], arguments = [args],
) )


devfiles = depset()
if ctx.attr.include_devmode_srcs:
for d in ctx.attr.deps:
devfiles = depset(transitive = [devfiles, d.files, d.node_sources])

package_dir = create_package(ctx, devfiles.to_list(), [npm_package_directory])
return struct( return struct(
files = depset([npm_package_directory]) files = depset([package_dir])
) )


NG_PACKAGE_ATTRS = dict(ROLLUP_ATTRS, **{ NG_PACKAGE_ATTRS = dict(NPM_PACKAGE_ATTRS, **dict(ROLLUP_ATTRS, **{
"srcs": attr.label_list(allow_files = True), "srcs": attr.label_list(allow_files = True),
"deps": attr.label_list(aspects = [ "deps": attr.label_list(aspects = [
rollup_module_mappings_aspect, rollup_module_mappings_aspect,
esm5_outputs_aspect, esm5_outputs_aspect,
sources_aspect,
]), ]),
"include_devmode_srcs": attr.bool(default = False),
"readme_md": attr.label(allow_single_file = FileType([".md"])), "readme_md": attr.label(allow_single_file = FileType([".md"])),
"globals": attr.string_dict(default={}), "globals": attr.string_dict(default={}),
"secondary_entry_points": attr.string_list(), "secondary_entry_points": attr.string_list(),
"_packager": attr.label( "_ng_packager": attr.label(
default=Label("//packages/bazel/src/ng_package:packager"), default=Label("//packages/bazel/src/ng_package:packager"),
executable=True, cfg="host"), executable=True, cfg="host"),
"_rollup": attr.label( "_rollup": attr.label(
Expand All @@ -352,22 +379,32 @@ NG_PACKAGE_ATTRS = dict(ROLLUP_ATTRS, **{
"_uglify": attr.label( "_uglify": attr.label(
default=Label("@build_bazel_rules_nodejs//internal/rollup:uglify"), default=Label("@build_bazel_rules_nodejs//internal/rollup:uglify"),
executable=True, cfg="host"), executable=True, cfg="host"),
}) }))

# Angular wants these named after the entry_point,
# eg. for //packages/core it looks like "packages/core/index.js", we want
# core.js produced by this rule.
# Currently we just borrow the entry point for this, if it looks like
# some/path/to/my/package/index.js
# we assume the files should be named "package.*.js"
def primary_entry_point_name(name, entry_point):
return entry_point.split("/")[-2] if entry_point.find("/") >=0 else name


def ng_package_outputs(name, entry_point): def ng_package_outputs(name, entry_point):
# Angular wants these named after the entry_point, basename = primary_entry_point_name(name, entry_point)
# eg. for //packages/core it looks like "packages/core/index.js", we want outputs = {
# core.js produced by this rule.
# Currently we just borrow the entry point for this, if it looks like
# some/path/to/my/package/index.js
# we assume the files should be named "package.*.js"
basename = entry_point.split("/")[-2] if entry_point.find("/") >=0 else name
return {
"fesm5": "fesm5/%s.js" % basename, "fesm5": "fesm5/%s.js" % basename,
"fesm2015": "fesm2015/%s.js" % basename, "fesm2015": "fesm2015/%s.js" % basename,
"umd": "%s.umd.js" % basename, "umd": "%s.umd.js" % basename,
"umd_min": "%s.umd.min.js" % basename, "umd_min": "%s.umd.min.js" % basename,
} }
for key in NPM_PACKAGE_OUTPUTS:
# NPM_PACKAGE_OUTPUTS is a "normal" dict-valued outputs so it looks like
# "pack": "%{name}.pack",
# But this is a function-valued outputs.
# Bazel won't replace the %{name} token so we have to do it.
outputs[key] = NPM_PACKAGE_OUTPUTS[key].replace("%{name}", name)
return outputs


ng_package = rule( ng_package = rule(
implementation = _ng_package_impl, implementation = _ng_package_impl,
Expand Down
Loading

0 comments on commit 88b3198

Please sign in to comment.