fix(bazel): replay compilation uses wrong compiler for building esm5 (#28053)

With the update to TypeScript 3.2.x, a big issue seems to have appeared for downstream Bazel users. If the downstream user still uses a lower TypeScript version, normal Bazel targets using the `ng_module` rule are still compiled with the correct/old TypeScript version (assuming they set the `node_modules` attribute properly).

But, if they build the previous Bazel targets by specifying them within a `ng_package` rule, the TypeScript version from the Angular `workspace` is being used for the replayed ESM5 compilation. This is because we resolve the replay compiler to `ngc_wrapped` or `tsc_wrapped` Bazel executables which are defined as part of the `angular` workspace. This means that the compilers are different if the downstream user uses `ngc-wrapped` from the `@npm` repository because the replayed compilation would use the compiler with `@ngdeps//typescript`.

In order to fix this, we should just use the compiler that is defined in the `@angular//BUILD.bazel` file. This target by defaults to the "@npm" workspace which is working for downstream users. This is similar to how it is handled for `tsc-wrapped`. `tsc-wrapped` works as expected for downstream users.

**Note**: This is not the ideal solution because ideally we would
completely respect the `compiler` option from the base `ng_module`, but
this is not possible in a hermetic way, unless we somehow accept the
`compiler` as an attribute that builds all transitive deps. This is
something we should explore in the future. For now, we just fix this in
a reasonable way that is also used for `tsc_wrapped` from the TypeScript
rules.

PR Close #28053
This commit is contained in:
Paul Gschwendtner 2019-01-10 23:38:06 +01:00 committed by Andrew Kushnir
parent e8495b460f
commit cd0451305a
1 changed files with 28 additions and 4 deletions

View File

@ -12,6 +12,8 @@ However we need to publish this flavor on NPM, so it's necessary to be able
to produce it.
"""
load(":external.bzl", "DEFAULT_NG_COMPILER")
# The provider downstream rules use to access the outputs
ESM5Info = provider(
doc = "Typescript compilation outputs in ES5 syntax with ES Modules",
@ -84,13 +86,23 @@ def _esm5_outputs_aspect(target, ctx):
],
)
replay_compiler = target.typescript.replay_params.compiler.path.split("/")[-1]
replay_compiler_path = target.typescript.replay_params.compiler.short_path
replay_compiler_name = replay_compiler_path.split("/")[-1]
# in windows replay_compiler path end with '.exe'
if replay_compiler.startswith("tsc_wrapped"):
if replay_compiler_name.startswith("tsc_wrapped"):
compiler = ctx.executable._tsc_wrapped
elif replay_compiler.startswith("ngc-wrapped"):
elif replay_compiler_name.startswith("ngc-wrapped"):
compiler = ctx.executable._ngc_wrapped
# BEGIN-INTERNAL
# If the "replay_compiler" path refers to "ngc_wrapped" from within the Angular workspace,
# we need to use "ngc_wrapped" from source. This is necessary because we don't have
# a "npm" workspace with the "@angular/bazel" NPM package installed.
if not replay_compiler_path.startswith("../"):
compiler = ctx.executable._internal_ngc_wrapped
# END-INTERNAL
else:
fail("Unknown replay compiler", target.typescript.replay_params.compiler.path)
@ -131,6 +143,14 @@ esm5_outputs_aspect = aspect(
# Recurse to the deps of any target we visit
attr_aspects = ["deps"],
attrs = {
# This is only used if the replay_compiler refers to the "angular" workspace. In that
# case we need to use "ngc_wrapped" from its source location because we can't have
# the "npm" workspace that has the "@angular/bazel" NPM package installed.
"_internal_ngc_wrapped": attr.label(
default = Label("//packages/bazel/src/ngc-wrapped"),
executable = True,
cfg = "host",
),
"_modify_tsconfig": attr.label(
default = Label("//packages/bazel/src:modify_tsconfig"),
executable = True,
@ -141,8 +161,12 @@ esm5_outputs_aspect = aspect(
executable = True,
cfg = "host",
),
# This is the default "ngc_wrapped" executable that will be used to replay the compilation
# for ESM5 mode. The default compiler consumes "ngc_wrapped" from the "@npm" workspace.
# This is needed for downstream Bazel users that can have a different TypeScript
# version installed.
"_ngc_wrapped": attr.label(
default = Label("//packages/bazel/src/ngc-wrapped"),
default = Label(DEFAULT_NG_COMPILER),
executable = True,
cfg = "host",
),