2020-06-25 04:32:41 -04:00
|
|
|
load("//tools:defaults.bzl", "pkg_npm", "ts_api_guardian_test", "ts_config", "ts_library")
|
2017-09-25 15:40:22 -04:00
|
|
|
|
2021-03-15 19:33:48 -04:00
|
|
|
# Load ng_perf_flag explicitly from ng_perf.bzl as it's private API, and not exposed to other
|
|
|
|
# consumers of @angular/bazel.
|
|
|
|
load("//packages/bazel/src:ng_perf.bzl", "ng_perf_flag")
|
|
|
|
|
2021-04-05 05:57:24 -04:00
|
|
|
package(default_visibility = ["//visibility:public"])
|
|
|
|
|
2017-09-25 15:40:22 -04:00
|
|
|
ts_config(
|
|
|
|
name = "tsconfig",
|
|
|
|
src = "tsconfig-build.json",
|
2017-12-06 09:56:49 -05:00
|
|
|
deps = ["//packages:tsconfig-build.json"],
|
2017-09-25 15:40:22 -04:00
|
|
|
)
|
2017-07-21 17:20:34 -04:00
|
|
|
|
|
|
|
ts_library(
|
|
|
|
name = "compiler-cli",
|
2017-12-06 09:56:49 -05:00
|
|
|
srcs = glob(
|
|
|
|
[
|
|
|
|
"*.ts",
|
|
|
|
"src/**/*.ts",
|
|
|
|
],
|
2017-12-18 00:36:21 -05:00
|
|
|
exclude = [
|
|
|
|
"src/integrationtest/**/*.ts",
|
|
|
|
],
|
2017-12-06 09:56:49 -05:00
|
|
|
),
|
|
|
|
tsconfig = ":tsconfig",
|
2017-07-21 17:20:34 -04:00
|
|
|
deps = [
|
2017-12-06 09:56:49 -05:00
|
|
|
"//packages/compiler",
|
2020-01-17 19:00:07 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/core",
|
|
|
|
"//packages/compiler-cli/src/ngtsc/core:api",
|
2018-08-23 17:33:38 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/diagnostics",
|
2019-06-06 15:22:32 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/file_system",
|
2020-05-28 19:08:52 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/incremental",
|
2019-06-10 12:19:35 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/indexer",
|
2019-03-18 14:16:38 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/perf",
|
fix(compiler-cli): ensure the compiler tracks `ts.Program`s correctly (#41291)
`NgCompiler` previously had a notion of the "next" `ts.Program`, which
served two purposes:
* it allowed a client using the `ts.createProgram` API to query for the
latest program produced by the previous `NgCompiler`, as a starting
point for building the _next_ program that incorporated any new user
changes.
* it allowed the old `NgCompiler` to be queried for the `ts.Program` on
which all prior state is based, which is needed to compute the delta
from the new program to ultimately determine how much of the prior
state can be reused.
This system contained a flaw: it relied on the `NgCompiler` knowing when
the `ts.Program` would be changed. This works fine for changes that
originate in `NgCompiler` APIs, but a client of the `TemplateTypeChecker`
may use that API in ways that create new `ts.Program`s without the
`NgCompiler`'s knowledge. This caused the `NgCompiler`'s concept of the
"next" program to get out of sync, causing incorrectness in future
incremental analysis.
This refactoring cleans up the compiler's `ts.Program` management in
several ways:
* `TypeCheckingProgramStrategy`, the API which controls `ts.Program`
updating, is renamed to the `ProgramDriver` and extracted to a separate
ngtsc package.
* It loses its responsibility of determining component shim filenames. That
functionality now lives exclusively in the template type-checking package.
* The "next" `ts.Program` concept is renamed to the "current" program, as
the "next" name was misleading in several ways.
* `NgCompiler` now wraps the `ProgramDriver` used in the
`TemplateTypeChecker` to know when a new `ts.Program` is created,
regardless of which API drove the creation, which actually fixes the bug.
PR Close #41291
2021-03-19 20:06:10 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/program_driver",
|
fix(compiler-cli): downlevel angular decorators to static properties (#37382)
In v7 of Angular we removed `tsickle` from the default `ngc` pipeline.
This had the negative potential of breaking ES2015 output and SSR due
to a limitation in TypeScript.
TypeScript by default preserves type information for decorated constructor
parameters when `emitDecoratorMetadata` is enabled. For example,
consider this snippet below:
```
@Directive()
export class MyDirective {
constructor(button: MyButton) {}
}
export class MyButton {}
```
TypeScript would generate metadata for the `MyDirective` class it has
a decorator applied. This metadata would be needed in JIT mode, or
for libraries that provide `MyDirective` through NPM. The metadata would
look as followed:
```
let MyDirective = class MyDir {}
MyDirective = __decorate([
Directive(),
__metadata("design:paramtypes", [MyButton]),
], MyDirective);
let MyButton = class MyButton {}
```
Notice that TypeScript generated calls to `__decorate` and
`__metadata`. These calls are needed so that the Angular compiler
is able to determine whether `MyDirective` is actually an directive,
and what types are needed for dependency injection.
The limitation surfaces in this concrete example because `MyButton`
is declared after the `__metadata(..)` call, while `__metadata`
actually directly references `MyButton`. This is illegal though because
`MyButton` has not been declared at this point. This is due to the
so-called temporal dead zone in JavaScript. Errors like followed will
be reported at runtime when such file/code evaluates:
```
Uncaught ReferenceError: Cannot access 'MyButton' before initialization
```
As noted, this is a TypeScript limitation because ideally TypeScript
shouldn't evaluate `__metadata`/reference `MyButton` immediately.
Instead, it should defer the reference until `MyButton` is actually
declared. This limitation will not be fixed by the TypeScript team
though because it's a limitation as per current design and they will
only revisit this once the tc39 decorator proposal is finalized
(currently stage-2 at time of writing).
Given this wontfix on the TypeScript side, and our heavy reliance on
this metadata in libraries (and for JIT mode), we intend to fix this
from within the Angular compiler by downleveling decorators to static
properties that don't need to evaluate directly. For example:
```
MyDirective.ctorParameters = () => [MyButton];
```
With this snippet above, `MyButton` is not referenced directly. Only
lazily when the Angular runtime needs it. This mitigates the temporal
dead zone issue caused by a limitation in TypeScript's decorator
metadata output. See: https://github.com/microsoft/TypeScript/issues/27519.
In the past (as noted; before version 7), the Angular compiler by
default used tsickle that already performed this transformation. We
moved the transformation to the CLI for JIT and `ng-packager`, but now
we realize that we can move this all to a single place in the compiler
so that standalone ngc consumers can benefit too, and that we can
disable tsickle in our Bazel `ngc-wrapped` pipeline (that currently
still relies on tsickle to perform this decorator processing).
This transformation also has another positive side-effect of making
Angular application/library code more compatible with server-side
rendering. In principle, TypeScript would also preserve type information
for decorated class members (similar to how it did that for constructor
parameters) at runtime. This becomes an issue when your application
relies on native DOM globals for decorated class member types. e.g.
```
@Input() panelElement: HTMLElement;
```
Your application code would then reference `HTMLElement` directly
whenever the source file is loaded in NodeJS for SSR. `HTMLElement`
does not exist on the server though, so that will become an invalid
reference. One could work around this by providing global mocks for
these DOM symbols, but that doesn't match up with other places where
dependency injection is used for mocking DOM/browser specific symbols.
More context in this issue: #30586. The TL;DR here is that the Angular
compiler does not care about types for these class members, so it won't
ever reference `HTMLElement` at runtime.
Fixes #30106. Fixes #30586. Fixes #30141.
Resolves FW-2196. Resolves FW-2199.
PR Close #37382
2020-06-05 10:26:23 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/reflection",
|
perf(compiler-cli): fix regressions in incremental program reuse (#37641)
Commit 4213e8d5 introduced shim reference tagging into the compiler, and
changed how the `TypeCheckProgramHost` worked under the hood during the
creation of a template type-checking program. This work enabled a more
incremental flow for template type-checking, but unintentionally introduced
several regressions in performance, caused by poor incrementality during
`ts.Program` creation.
1. The `TypeCheckProgramHost` was made to rely on the `ts.CompilerHost` to
retrieve instances of `ts.SourceFile`s from the original program. If the
host does not return the original instance of such files, but instead
creates new instances, this has two negative effects: it incurs
additional parsing time, and it interferes with TypeScript's ability to
reuse information about such files.
2. During the incremental creation of a `ts.Program`, TypeScript compares
the `referencedFiles` of `ts.SourceFile` instances from the old program
with those in the new program. If these arrays differ, TypeScript cannot
fully reuse the old program. The implementation of reference tagging
introduced in 4213e8d5 restores the original `referencedFiles` array
after a `ts.Program` is created, which means that future incremental
operations involving that program will always fail this comparison,
effectively limiting the incrementality TypeScript can achieve.
Problem 1 exacerbates problem 2: if a new `ts.SourceFile` is created by the
host after shim generation has been disabled, it will have an untagged
`referencedFiles` array even if the original file's `referencedFiles` was
not restored, triggering problem 2 when creating the template type-checking
program.
To fix these issues, `referencedFiles` arrays are now restored on the old
`ts.Program` prior to the creation of a new incremental program. This allows
TypeScript to get the most out of reusing the old program's data.
Additionally, the `TypeCheckProgramHost` now uses the original `ts.Program`
to retrieve original instances of `ts.SourceFile`s where possible,
preventing issues when a host would otherwise return fresh instances.
Together, these fixes ensure that program reuse is as incremental as
possible, and tests have been added to verify this for certain scenarios.
An optimization was further added to prevent the creation of a type-checking
`ts.Program` in the first place if no type-checking is necessary.
PR Close #37641
2020-06-19 15:55:13 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/shims",
|
2020-09-11 11:43:23 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/translator",
|
perf(compiler-cli): split Ivy template type-checking into multiple files (#36211)
As a performance optimization, this commit splits the single
__ngtypecheck__.ts file which was previously added to the user's program as
a container for all template type-checking code into multiple .ngtypecheck
shim files, one for each original file in the user's program.
In larger applications, the generation, parsing, and checking of this single
type-checking file was a huge performance bottleneck, with the file often
exceeding 1 MB in text content. Particularly in incremental builds,
regenerating this single file for the entire application proved especially
expensive.
This commit introduces a new strategy for template type-checking code which
makes use of a new interface, the `TypeCheckingProgramStrategy`. This
interface abstracts the process of creating a new `ts.Program` to type-check
a particular compilation, and allows the mechanism there to be kept separate
from the more complex logic around dealing with multiple .ngtypecheck files.
A new `TemplateTypeChecker` hosts that logic and interacts with the
`TypeCheckingProgramStrategy` to actually generate and return diagnostics.
The `TypeCheckContext` class, previously the workhorse of template type-
checking, is now solely focused on collecting and generating type-checking
file contents.
A side effect of implementing the new `TypeCheckingProgramStrategy` in this
way is that the API is designed to be suitable for use by the Angular
Language Service as well. The LS also needs to type-check components, but
has its own method for constructing a `ts.Program` with type-checking code.
Note that this commit does not make the actual checking of templates at all
_incremental_ just yet. That will happen in a future commit.
PR Close #36211
2020-03-04 18:50:12 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/typecheck",
|
2021-01-06 17:17:45 -05:00
|
|
|
"//packages/compiler-cli/src/ngtsc/typecheck/api",
|
2019-02-20 12:54:42 -05:00
|
|
|
"@npm//@bazel/typescript",
|
2019-06-22 00:52:00 -04:00
|
|
|
"@npm//@types/node",
|
2020-02-12 05:52:15 -05:00
|
|
|
"@npm//chokidar",
|
2019-11-13 02:17:06 -05:00
|
|
|
"@npm//minimist",
|
2019-05-09 17:51:51 -04:00
|
|
|
"@npm//reflect-metadata",
|
2019-02-20 12:54:42 -05:00
|
|
|
"@npm//tsickle",
|
|
|
|
"@npm//typescript",
|
2017-07-21 17:20:34 -04:00
|
|
|
],
|
|
|
|
)
|
2018-03-13 14:00:53 -04:00
|
|
|
|
2019-12-28 19:37:59 -05:00
|
|
|
pkg_npm(
|
2018-03-13 14:00:53 -04:00
|
|
|
name = "npm_package",
|
|
|
|
srcs = [
|
|
|
|
"package.json",
|
|
|
|
],
|
2018-06-05 14:38:46 -04:00
|
|
|
tags = [
|
|
|
|
"release-with-framework",
|
|
|
|
],
|
2018-12-11 19:53:42 -05:00
|
|
|
# Do not add more to this list.
|
|
|
|
# Dependencies on the full npm_package cause long re-builds.
|
2019-01-22 12:46:51 -05:00
|
|
|
visibility = [
|
2020-02-04 14:45:40 -05:00
|
|
|
"//integration:__pkg__",
|
2019-01-22 12:46:51 -05:00
|
|
|
"//packages/compiler-cli/integrationtest:__pkg__",
|
|
|
|
],
|
2018-07-16 03:49:56 -04:00
|
|
|
deps = [
|
|
|
|
":compiler-cli",
|
2020-12-17 15:15:02 -05:00
|
|
|
"//packages/compiler-cli/linker",
|
|
|
|
"//packages/compiler-cli/linker/babel",
|
2019-03-20 09:47:58 -04:00
|
|
|
"//packages/compiler-cli/ngcc",
|
2020-07-08 10:23:02 -04:00
|
|
|
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
|
|
|
"//packages/compiler-cli/src/ngtsc/logging/testing",
|
2018-07-16 03:49:56 -04:00
|
|
|
],
|
2018-03-13 14:00:53 -04:00
|
|
|
)
|
2020-02-26 12:09:35 -05:00
|
|
|
|
|
|
|
ts_api_guardian_test(
|
|
|
|
name = "error_code_api",
|
2020-03-12 07:36:28 -04:00
|
|
|
actual = "angular/packages/compiler-cli/npm_package/src/ngtsc/diagnostics/src/error_code.d.ts",
|
2020-02-26 12:09:35 -05:00
|
|
|
data = [
|
|
|
|
":npm_package",
|
|
|
|
"//goldens:public-api",
|
|
|
|
],
|
2020-03-12 07:36:28 -04:00
|
|
|
golden = "angular/goldens/public-api/compiler-cli/error_code.d.ts",
|
2020-02-26 12:09:35 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
ts_api_guardian_test(
|
|
|
|
name = "compiler_options_api",
|
2020-03-12 07:36:28 -04:00
|
|
|
actual = "angular/packages/compiler-cli/npm_package/src/ngtsc/core/api/src/public_options.d.ts",
|
2020-02-26 12:09:35 -05:00
|
|
|
data = [
|
|
|
|
":npm_package",
|
|
|
|
"//goldens:public-api",
|
|
|
|
],
|
2020-03-12 07:36:28 -04:00
|
|
|
golden = "angular/goldens/public-api/compiler-cli/compiler_options.d.ts",
|
2020-02-26 12:09:35 -05:00
|
|
|
)
|
2021-03-15 19:33:48 -04:00
|
|
|
|
|
|
|
# Controls whether the Ivy compiler produces performance traces as part of each build
|
|
|
|
ng_perf_flag(
|
|
|
|
name = "ng_perf",
|
|
|
|
build_setting_default = False,
|
|
|
|
)
|