Bazel has a restriction that a single output (eg. a compiled version of
//packages/common) can only be produced by a single rule. This precludes
the Angular repo from having multiple rules that build the same code. And
the complexity of having a single rule produce multiple outputs (eg. an
ngc-compiled version of //packages/common and an Ivy-enabled version) is
too high.
Additionally, the Angular repo has lots of existing tests which could be
executed as-is under Ivy. Such testing is very valuable, and it would be
nice to share not only the code, but the dependency graph / build config
as well.
Thus, this change introduces a --define flag 'compile' with three potential
values. When --define=compile=X is set, the entire build system runs in a
particular mode - the behavior of all existing targets is controlled by
the flag. This allows us to reuse our entire build structure for testing
in a variety of different manners. The flag has three possible settings:
* legacy (the default): the traditional View Engine (ngc) build
* local: runs the prototype ngtsc compiler, which does not rely on global
analysis
* jit: runs ngtsc in a mode which executes tsickle, but excludes the
Angular related transforms, which approximates the behavior of plain
tsc. This allows the main packages such as common to be tested with
the JIT compiler.
Additionally, the ivy_ng_module() rule still exists and runs ngc in a mode
where Ivy-compiled output is produced from global analysis information, as
a stopgap while ngtsc is being developed.
PR Close#24056
This commit adds a new compiler pipeline that isn't dependent on global
analysis, referred to as 'ngtsc'. This new compiler is accessed by
running ngc with "enableIvy" set to "ngtsc". It reuses the same initialization
logic but creates a new implementation of Program which does not perform the
global-level analysis that AngularCompilerProgram does. It will be the
foundation for the production Ivy compiler.
PR Close#23455
Lowering expressions in flat module metadata is desirable, but it won't
work without some rearchitecting. Currently the flat module index source
is added to the Program and therefore must be determined before the rest
of the transforms run. Since the lowering transform changes the set of
exports needed in the index, this creates a catch-22 in the index
generation.
This commit causes the flat module index metadata to be generated using
only those transforms which are "safe" (don't modify the index).
PR Close#23226
Currently, the flat module index metadata is produced directly from
the source metadata. The compiler, however, applies transformations
on the Typescript sources during transpilation, and also equivalent
transformations on the metadata itself. This transformed metadata
doesn't end up in the flat module index.
This changes the compiler to generate the flat module index metadata
from its transformed version instead of directly from source.
PR Close#23129
Computing the value of loadChildren does not work externally, as the CLI
needs to be able to detect the paths referenced to properly set up
codesplitting. However, internally, different approaches to codesplitting
require hashed module IDs, and the computation of those hashes involves
something like:
{path: '...', loadChildren: hashFn('module')}
ngc should lower loadChildren into an exported constant in that case.
This will never break externally, because loadChildren is always a
string externally, and a string won't get lowered.
PR Close#23088
ngc knows to filter out d.ts inputs, but the logic accidentally
depended on whether it had a previous Program lying around.
Fixing that logic puts ngc on the fast code path, but in that code
path it must be able to merge tsickle EmitResults, so we need to
plumb the tsickle.mergeEmitResults function through all the intervening
APIs. The bulk of this change is that plumbing.
PR Close#22899
This adds compilation of @NgModule providers and imports into
ngInjectorDef statements in generated code. All @NgModule annotations
will be compiled and the @NgModule decorators removed from the
resultant js output.
All @Injectables will also be compiled in Ivy mode, and the decorator
removed.
PR Close#22458
BREAKING CHANGE:
The `<template>` tag was deprecated in Angular v4 to avoid collisions (i.e. when
using Web Components).
This commit removes support for `<template>`. `<ng-template>` should be used
instead.
BEFORE:
<!-- html template -->
<template>some template content</template>
# tsconfig.json
{
# ...
"angularCompilerOptions": {
# ...
# This option is no more supported and will have no effect
"enableLegacyTemplate": [true|false]
}
}
AFTER:
<!-- html template -->
<ng-template>some template content</ng-template>
PR Close#22783
Closure has a transformation which turns:
Service.ngInjectableDef = ...;
into:
Service$ngInjectableDef = ...;
This transformation obviously breaks Ivy in a major way. The solution is
to annotate the fields as @nocollapse. However, Typescript appears to ignore
synthetic comments added to a node during a transformation, so the "right"
way to add these comments doesn't work.
As an interim measure, a post-processing step just before the compiled JS is
written to disk appends the correct comments with a regular expression.
PR Close#22691
Previously the flag would only disable the check in the case we tried to use newer tsc version.
In g3 we sometimes take a while to update tsc, but as a prerequisite of that Angular needs to be
updated first. This change enables us to update Angular and use it in g3 while g3 is being update
to the required tsc. Of course extra care is required when this check is disabled, but since we
control everything in g3, it's on us to get this right.
I don't see any preexisting tests for this, and I'm not sure how to write them right now.
I filed https://github.com/angular/angular/issues/22699
PR Close#22669
When angularCompilerOptions { enableResourceInlining: true }, we replace all templateUrl and styleUrls properties in @Component with template/styles
PR Close#22615
This commit bundles 3 important changes, with the goal of enabling tree-shaking
of services which are never injected. Ordinarily, this tree-shaking is prevented
by the existence of a hard dependency on the service by the module in which it
is declared.
Firstly, @Injectable() is modified to accept a 'scope' parameter, which points
to an @NgModule(). This reverses the dependency edge, permitting the module to
not depend on the service which it "provides".
Secondly, the runtime is modified to understand the new relationship created
above. When a module receives a request to inject a token, and cannot find that
token in its list of providers, it will then look at the token for a special
ngInjectableDef field which indicates which module the token is scoped to. If
that module happens to be in the injector, it will behave as if the token
itself was in the injector to begin with.
Thirdly, the compiler is modified to read the @Injectable() metadata and to
generate the special ngInjectableDef field as part of TS compilation, using the
PartialModules system.
Additionally, this commit adds several unit and integration tests of various
flavors to test this change.
PR Close#22005
The "enableIvy" compiler option is the initial implementation
of the Render3 (or Ivy) code generation. This commit enables
generation generating "Hello, World" (example in the test)
but not much else. It is currenly only useful for internal Ivy
testing as Ivy is in development.
PR Close#21427
Previously, this code would unconditionally add a @fileoverview
comment to generated files, and only if the contained any code at all.
However often existing fileoverview comments should be copied from the
file the generated file was originally based off of. This allows users
to e.g. include Closure Compiler directives in their original
`component.ts` file, which will then automaticallly also apply to code
generated from it.
This special cases `@license` comments, as Closure disregards directives
in comments containing `@license`.
PR Close#20870
Saving `oldProgram` in `AngularCompilerProgram` instances is causing a memory leak for unemitted programs.
It's not actually used so simply not saving it fixes the memory leak.
Fix#20691
PR Close#20692
The errors produced when error were encountered while interpreting the
content of a directive was often incomprehencible. With this change
these kind of error messages should be easier to understand and diagnose.
PR Close#20459
Condition: static analysis error, given:
- noResolve:true
- generateCodeForLibraries: false
- CompilerHost.getSourceFile throws on non existent files
All of these are true in G3.
PR Close#20041
This also changes the compiler so that we throw less often
on structural changes and produce a meaningful state
in the `ng.Program` in case of errors.
Related to #19951
PR Close#19953
The path mapping was broken for Windows by fc0b1d5b610408a59f13f86d96d85b5f498d97ff.
Fixed the path mapping and put code in place to make such a problem
to sneek by again.
PR Close#19915
The error collector changes behavior of the metadata resolver
in ways that haven't been fully hardened. This changes limits
its use to the lazy route detection and the language service.
Issue: #19906
PR Close#19912
This change is needed to prevent users’ builds from breaking.
If a user sets `fullTemlateTypeCheck` to true, we will
continue to check the templates even when `skipTemplateCodegen` is true
as well.
Related to #19906
PR Close#19909
This fixes a problem introduced in 8d45fefc313aebd0db7b320a1d324c2d4bebd268
which modified how diagnostic error messages are reported for structural
metadata errors causing some of the diagnostics to be lost.
PR Close#19886
Usages of `NgTools_InternalApi_NG_2` from `@angular/compiler-cli` will now
throw an error.
Adds `listLazyRoutes` to `@angular/compiler-cli/ngtools2.ts` for getting
the lazy routes of a `ng.Program`.
PR Close#19836
If no user files changed:
- only type check the changed generated files
Never emit non changed generated files
- we still calculate them, but don’t send them through
TypeScript to emit them but cache the written files instead.
PR Close#19646
This helps hazel as it does not check libraries (e.g. the default lib) which are
not input files, but still checks `.d.ts` files that are inputs.
PR Close#19581
For now, we always create all generated files, but diff them
before we pass them to TypeScript.
For the user files, we compare the programs and only emit changed
TypeScript files.
This also adds more diagnostic messages if the `—diagnostics` flag
is passed to the command line.