There was a problem with a combination of the `eager` URL update, browser `back` button, and hybrid applications. Details provided in internal ticket http://b/123667227.
This fix handles the problem by setting `router.browserUrlTree` when all conditions have failed, meaning the browser doesn't do anything with the navigation other than update internal data structures. Without this change, the problem was an old value was stored in `router.broserUrlTree` causing some new navigations to be compared to an old value and breaking future navigations.
PR Close#30160
In the existing implementation the `elementPropertyInternal` function (meant to
set element properties) was executed even if a bound value didn't change. The
`elementPropertyInternal` was inspecting the incoming value and after comparing it
to `NO_CHANGE` - exiting early. All in all it meant that we were unnecessarily
invoking the `elementPropertyInternal` function for cases where bound value didn't
change.
Based on my bencharks (running change detection without any model update in a tight
loop) this unnecessary function call was causing ~5% slowdown in the change detection
process.
PR Close#30255
This commit fixes a regression introduced in PR 29692 where
the interpolate symbol in View Engine was improperly prefixed
with the ɵɵ that signifies private instructions for Ivy. It
resulted in interpolations of 10+ values not working correctly
in AOT mode. This commit removes the prefix.
PR Close#30243
Previously, `R3TestBedCompiler` was dynamically defining an
`@NgModule`-decorated `CompilerModule` class inside a method call.
Since ngcc only processes top-level classes, this class was not
transformed causing failures in unit tests (see #30121 for details).
This commit fixes it by using `compileNgModuleDefs()` directly (similar
to the fix in #30037).
Fixes#30121
PR Close#28530
Sometimes we need to override module resolution behaviour.
We do this by implementing the optional method `resolveModuleNames()`
on `CompilerHost`.
This commit ensures that we always try this method first before falling
back to the standard `ts.resolveModuleName`
PR Close#30017
Packages that do not follow APF may have the declaration files in the same
directory as one source format, typically ES5. This is problematic for ngcc,
as it needs to create a TypeScript program with all JavaScript sources of
an entry-point, whereas TypeScript's module resolution mechanism would have
resolved an internal module import to the external facing .d.ts declaration
file, instead of the JavaScript source file. This behavior results in the
program to be analysed being incomplete.
This commit introduces a custom compiler host that recognizes the above
scenario and rewires the resolution of a .d.ts declaration file to its
JavaScript counterpart, if applicable.
Fixes#29939
PR Close#30017
Ivy uses R3Injector, but we are currently pulling in both the StaticInjector
(View Engine injector) and the R3Injector when running with Ivy. This commit
adds an ivy switch so calling Injector.create() pulls in the correct
implementation of the injector depending on whether you are using VE or Ivy.
This saves us about 3KB in the bundle.
PR Close#30219
Previously, we were supporting injection flags for provider deps, but only
if they fit the format `new Optional()`. This commit fixes resolution of
provider deps to also support `Optional` (without the new). This keeps us
backwards compatible with what View Engine supported.
PR Close#30216
Stores the views that are part of a container directly on the `LContainer`, rather than maintaining a dedicated sub-array.
This PR resolves FW-1288.
PR Close#30179
Currently, we are not properly resolving forward refs when they appear
in deps for providers created with the useFactory strategy. This commit
wraps provider deps in the resolveForwardRef call so the tokens are
passed into the inject function as expected.
PR Close#30201
Fixes `HostBinding` and `HostListener` declarations not being inherited from base classes that don't have an Angular decorator.
This PR resolves FW-1275.
PR Close#30158
Currently the `static-query` migrations fails at the final step of
updating a query when the query already specifies options which
cannot be transformed easily. e.g. the options are computed through
a function call: `@ViewChild(..., getQueryOpts());` or `@ViewChild(..., myOptionsVar)`.
In these cases we technically could add additionally logic to update
the query options, but given that this is an edge-case and it's
potentially over-engineering the migration schematic, we just
always add a TODO for the timing and print out the determined
query timing in the console. The developer in that case just needs
to manually update the logic for the query options to contain the
printed query timing.
Potentially related to: https://github.com/angular/angular-cli/issues/14298
PR Close#30178
This PR adds the implementation for `definitionAndBoundSpan` because
it's now preferred over `definition`. vscode would send this new request
for `Go to definition`. As part of this PR the implementation for
`definition` is refactored and simplified. Goldens for both methods are
checked in.
PR Close#30125
This commit introduces a new interface, which abstracts access
to the underlying `FileSystem`. There is initially one concrete
implementation, `NodeJsFileSystem`, which is simply wrapping the
`fs` library of NodeJs.
Going forward, we can provide a `MockFileSystem` for test, which
should allow us to stop using `mock-fs` for most of the unit tests.
We could also implement a `CachedFileSystem` that may improve the
performance of ngcc.
PR Close#29643
By passing a `pathMappings` configuration (a subset of the
`ts.CompilerOptions` interface), we can instuct ngcc to process
additional paths outside the `node_modules` folder.
PR Close#29643
When working out the dependencies between entry-points
ngcc must parse the import statements and then resolve the
import path to the actual file. This is complicated because module
resolution is not trivial.
Previously ngcc used the node.js `require.resolve`, with some
hacking to resolve modules. This change refactors the `DependencyHost`
to use a new custom `ModuleResolver`, which is optimized for this use
case.
Moreover, because we are in full control of the resolution,
we can support TS `paths` aliases, where not all imports come from
`node_modules`. This is the case in some CLI projects where there are
compiled libraries that are stored locally in a `dist` folder.
See //FW-1210.
PR Close#29643
Previously we completely ignored entry-points that had not been
compiled with Angular, since we do not need to compile them
with ngcc. But this makes it difficult to reason about dependencies
between entry-points that were compiled with Angular and those that
were not.
Now we do track these non-Angular compiled entry-points but they
are marked as `compiledByAngular: false`.
PR Close#29643
The test now attempts to compile an entry-point (@angular/common/http/testing)
that has a transient "private" dependency. A private dependency is one that is
only visible by looking at the compiled JS code, rather than the generated TS
typings files.
This proves that we can't rely on typings files alone for computing the
dependencies between entry-points.
PR Close#29643
The `Transformer` and `Renderer` classes do not
actually need a `sourcePath` value as by the time
they are doing their work we are only working directly
with full absolute paths.
PR Close#29643
Introduces a new Bazel test that allows us to inspect
what source-files contribute to a given bundled file
and how much bytes they contribute to the bundle size.
Additionally the size-tracking rule groups the size
data by directories. This allows us to compare size
changes in the scope of directories. e.g. a lot of
files in a directory could increase slightly in size, but
in the directory scope the size change could be significant
and needs to be reported by the test target.
Resolves FW-1278
PR Close#30070
Disables the injectable pipe migration until we can decide whether this is the right solution for Ivy. Rolling it out properly will involve a more detailed plan and more changes like updating the styleguide, scaffolding schematics etc.
Context for the new `test-migrations.json`: since we use the `migrations.json` both for the real migrations and for tests, it doesn't allow us to disable a schematic, but continue running its tests. This change adds the test-specific file so that we can continue running the `injectable-pipe` tests, even though the schematic itself is disabled.
PR Close#30180
Currently the injectable pipe schematic generates invalid imports like `import import { Pipe, PipeTransform, Injectable } from '@angular/core'; from '@angular/core';`. The issue wasn't caught by the unit tests, because the invalid import still contains the valid one.
Fixes#30159.
PR Close#30170
This PR removes `tsserverlibrary` from rollup globals since the symbol
should not appear by the time rollup is invoked. `tsserverlibrary` is
used for types only, so the import statement should not be emitted by
tsc.
PR Close#30123
Fixes Ivy reflecting properties with `undefined` values, rather than omitting them. Also fixes that Ivy doesn't clear the reflected values when property value changes from something that is defined to undefined.
This PR resolves FW-1277.
PR Close#30103
Move tests for special tokens like `Injector`, `ElementRef`, `TemplateRef`, `ViewContainerRef`, `ChangeDectetorRef` and custom string tokens.
PR Close#29299
- Extracts and documents code that will be common to interpolation instructions
- Ensures that binding indices are updated at the proper time during compilation
- Adds additional tests
Related #30011
PR Close#30129
Prior to this commit, we were pulling DebugNode and DebugElement
into production builds because BrowserModule automatically pulled
in NgProbe and thus getDebugNode. In Ivy, this is not necessary
because Ivy has its own set of debug utilities. We should use these
existing tools instead of NgProbe.
This commit adds an Ivy switch so we do not pull in NgProbe utilities
when running with Ivy. This saves us ~8KB in prod builds.
PR Close#30130
Leading trivia, such as whitespace or comments, is
confusing for developers looking at source-mapped
templates, since they expect the source-map segment
to start after the trivia.
This commit adds skipping trivial characters to the lexer;
and then implements that in the template parser.
PR Close#30095
Previously, the ServiceWorker registration options should be defined as
an object literal (in order for them to be compatible with Ahead-of-Time
compilation), thus making it impossible to base the ServiceWorker
behavior on runtime conditions.
This commit allows specifying the registration options using a regular
provider, which means that it can take advantage of the `useFactory`
option to determine the config at runtime, while still remaining
compatible with AoT compilation.
PR Close#21842
With #30058, the ngUpgrade internal `angular.module()` method was
renamed to `angular.module_()` (to avoid a webpack bug).
Merging #29794 afterwards resulted in some broken tests, because it
still used the old `angular.module()` method name. (The PR had been
tested on CI against a revision that did not contain the rename.)
This commit fixes the broken tests by renaming the remaining occurrences
of `angular.module()`.
PR Close#30126
Previously, under certain circumstances, `NgZone#onMicrotaskEmpty` could
emit while a `$digest` was in progress, thus triggering another
`$digest`, which in turn would throw a `$digest already in progress`
error. Furthermore, throwing an error from inside the `onMicrotaskEmpty`
subscription would result in unsubscribing and stop triggering further
`$digest`s, when `onMicrotaskEmpty` emitted.
Usually, emitting while a `$digest` was already in progress was a result
of unintentionally running some part of AngularJS outside the Angular
zone, but there are valid (if rare) usecases where this can happen
(see #24680 for details).
This commit addresses the issue as follows:
- If a `$digest` is in progress when `onMicrotaskEmpty` emits, do not
trigger another `$digest` (to avoid the error). `$evalAsync()` is used
instead, to ensure that the bindings are evaluated at least once more.
- Since there is still a high probability that the situation is a result
of programming error (i.e. some AngularJS part running outside the
Angular Zone), a warning will be logged, but only if the app is in
[dev mode][1].
[1]: https://github.com/angular/angular/blob/78146c189/packages/core/src/util/ng_dev_mode.ts#L12Fixes#24680
PR Close#29794
Previously, ngtsc included query fields in the list of fields which can
affect the type of a directive via its type constructor. This feature
however has yet to be built, and View Engine in default mode does not
do this inference.
This caused an unexpected bug where private query fields (which should be
an error but are allowed by View Engine) cause the type constructor
signature to be invalid. This commit fixes that issue by disabling the
logic to include query fields.
PR Close#30094
ngtsc generates type constructors which infer the type of a directive based
on its inputs. Previously, a bug existed where this inference would fail in
the case of 'any' input values. For example, the inference of NgForOf fails
when an 'any' is provided, as it causes TypeScript to attempt to solve:
T[] = any
In this case, T gets inferred as {}, the empty object type, which is not
desirable.
The fix is to assign generic types in type constructors a default type of
'any', which TypeScript uses instead of {} when inference fails.
PR Close#30094
The proposed ES dynamic import() is now supported by the Angular CLI and the
larger toolchain. This renders the `loadChildren: string` API largely
redundant, as import() is far more natural, is less error-prone, and is
standards compliant. This commit deprecates the `string` form of
`loadChildren` in favor of dynamic import().
DEPRECATION:
When defining lazy-loaded route, Angular previously offered two options for
configuring the module to be loaded, both via the `loadChildren` parameter
of the route. Most Angular developers are familiar withthe `string` form of
this API. For example, the following route definition configures Angular to
load a `LazyModule` NgModule from `lazy-route/lazy.module.ts`:
```
[{
path: 'lazy',
loadChildren: 'lazy-route/lazy.module#LazyModule',
}]
```
This "magic string" configuration was previously necessary as there was
no dynamic module loading standard on the web. This has changed with the
pending standardization of dynamic `import()` expressions, which are now
supported in the Angular CLI and in web tooling in general. `import()`
offers a more natural and robust solution to dynamic module loading. The
above example can be rewritten to use dynamic `import()`:
```
[{
path: 'lazy',
loadChildren: () => import('./lazy-route/lazy.module').then(mod => mod.LazyModule),
}]
```
This form of lazy loading offers significant advantages in terms of:
* type checking via TypeScript
* simplicity of generated code
* future potential to run natively in supporting browsers
(see: [caniuse: dynamic import()](https://caniuse.com/#feat=es6-module-dynamic-import))
As a result, Angular is deprecating the `loadChildren: string` syntax in
favor of ES dynamic `import()`. An automatic migration will run during
`ng upgrade` to convert your existing Angular code to the new syntax.
PR Close#30073
When targeting ES2015 (as is the default in cli@8), `const` is not
downleveled to `var` and thus declaring `const module` throws an error
due to webpack wrapping the code in a function call with a `module`
argument (even when compiling for the `web` environment).
Related: webpack/webpack#7369
Fixes#30050
PR Close#30058
This commit provides a replacement for `$location`. The new service is written in Angular, and can be consumed into existing applications by using the downgraded version
of the provider.
Prior to this addition, applications upgrading from AngularJS to Angular could get into a situation where AngularJS wanted to control the URL, and would often parse or se
rialize the URL in a different way than Angular. Additionally, AngularJS was alerted to URL changes only through the `$digest` cycle. This provided a buggy feedback loop
from Angular to AngularJS.
With this new `LocationUpgradeProvider`, the `$location` methods and events are provided in Angular, and use Angular APIs to make updates to the URL. Additionally, change
s to the URL made by other parts of the Angular framework (such as the Router) will be listened for and will cause events to fire in AngularJS, but will no longer attempt
to update the URL (since it was already updated by the Angular framework).
This centralizes URL reads and writes to Angular and should help provide an easier path to upgrading AngularJS applications to Angular.
PR Close#30055
This abstract class (and AngularJSUrlCodec) are used for serializing and deserializing pieces of a URL string. AngularJS had a different way of doing this than Angular, and using this class in conjunction with the LocationUpgradeService an application can have control over how AngularJS URLs are serialized and deserialized.
PR Close#30055
When using the `history` API, setting a new `state` and retrieving it does not pass a `===` test to the object used to set the state. In other words, `history.state` is always a copy. This change makes the `MockPlatformLocation` behave in the same way.
PR Close#30055
This feature adds an `onUrlChange` to Angular's `Location` class. This is useful to track all updates coming from anywhere in the framework. Without this method, it's difficult (or impossible) to track updates run through `location.go()` or `location.replaceState()` as the browser doesn't publish events when `history.pushState()` or `.replaceState()` are run.
PR Close#30055
AngularJS's `$location` service doesn't have a direct counterpart in Angular. This is largely because the `Location` service in Angular was pulled out of the `Router`, but was not purpose-built to stand on its own.
This commit adds a new `@angular/common/upgrade` package with the beginnings of a new `LocationUpgradeService`. This service will more closely match the API of AngularJS and provide a way to replace the `$location` service from AngularJS.
PR Close#30055
Without this change, the framework doesn't surface URL parts such as hostname, protocol, and port. This makes it difficult to rebuild a complete URL. This change provides new APIs to read these values.
PR Close#30055
Previously there wasn't a way to retrieve `history.state` from the `Location` service. The only time the framework exposed this value was in navigation events. This meant if you weren't using the Angular router, there wasn't a way to get access to this `history.state` value other than going directly to the DOM.
This PR adds an API to retrieve the value of `history.state`. This will be useful and needed to provide a backwards-compatible `Location` service that can emulate AngularJS's `$location` service since we will need to be able to read the state data in order to produce AngularJS location transition events.
This feature will additionally be useful to any application that wants to access state data through Angular rather than going directly to the DOM APIs.
PR Close#30055
Prior to this change we had a MockLocationStrategy to replace the Path and Hash Location Strategies. However, there wasn't a good way to test the PlatformLocation which is needed for doing things such as setting history.state, using back()/forward(), etc.
PR Close#30055
ngtsc previously could attempt to reuse the main ts.Program twice. This
occurred when template type-checking was enabled and then an incremental
build was performed. This breaks a TypeScript invariant - ts.Programs can
only be reused once.
The creation of the template type-checking program reuses the main program,
rendering it moot. Then, on the next incremental build the main program
would be subject to reuse again, which would crash inside TypeScript.
This commit fixes the issue by reusing the template type-checking program
from the previous run on the next incremental build. Since under normal
circumstances the files in the type-checking program aren't changed, this
should be just as fast.
Testing strategy: a test is added in the incremental_spec which validates
that program reuse with type-checking turned on does not crash the compiler.
Fixes#30079
PR Close#30090
The `renderStringify` function is used in a lot of performance-sensitive places, however it contains a megamorphic read which is used primarily for error messages. These changes introduce a new function that can be used to stringify output for errors and removes the megamorphic read from `renderStringify`.
This PR resolves FW-1286.
PR Close#30082
Only the JS files that are actually part of the entry-point
should be copied to the new entry-point folder in the
`NewEntryPointFileWriter`.
Previously some typings and external JS files were
being copied which was messing up the node_modules
structure.
Fixes https://github.com/angular/angular-cli/issues/14193
PR Close#30085
When `ng add` is invoked independently of `ng new`, a node installation
of `@angular/bazel` is performed by the CLI before invoking the
schematic. This step appends `@angular/bazel` to the `dependencies`
section of `package.json`. The schematics then appends the same package
to `devDependencies`.
This leads to the warning:
```
warning package.json: "dependencies" has dependency "@angular/bazel" with
range "^8.0.0-beta.13" that collides with a dependency in "devDependencies"
of the same name with version "~8.0.0-beta.12"
```
PR Close#30072
Fixes view and content queries not being inherited in Ivy, if the base class hasn't been annotated with an Angular decorator (e.g. `Component` or `Directive`).
Also reworks the way the `ngBaseDef` is created so that it is added at the same point as the queries, rather than inside of the `Input` and `Output` decorators.
This PR partially resolves FW-1275. Support for host bindings will be added in a follow-up, because this PR is somewhat large as it is.
PR Close#30015
Prior to this commit, the check that verifies correct "id" field type was too strict and didn't allow `module.id` as @NgModule's "id" field value. This change adds a special handling for `module.id` and uses it as id of @NgModule if specified.
PR Close#30040
Now that ngtsc performs type checking using a dedicated `__ng_typecheck__.ts`
file, `NgtscProgram` always wraps its `ts.CompilerHost` in a shim host. This
shim fails to delegate `resolveModuleNames` so no custom module resolution
logic is considered. This introduces a problem for the CLI, as the compiler
host it passes kicks of ngcc for any imported module such that Ivy's
compatibility compiler runs automatically behind the scenes.
This commit adds delegation of the `resolveModuleNames` to fix the issue.
Fixes#30064
PR Close#30068
Previously, an instance of HttpParams would retain its list of mutations
after they have been materialized as a result of a read operation. Not
only does this unnecessarily hold onto memory, more importantly does it
introduce a bug where branching of off a materialized instance would
reconsider the set of mutations that had already been applied, resulting
in repeated application of mutations.
This commit fixes the bug by clearing the list of pending mutations
after they have been materialized, such that they will not be considered
once again for branched off instances.
Fixes#20430
PR Close#29045
Currently when someone runs `ng update` with the static-query migration,
the migration can fail with an error saying that the `AOT` compiler could not
be created. This can happen if the CLI project contains a test `tsconfig.json`
that is picked up by the schematic.
Due to the fact that spec tsconfig files cannot be ran with NGC (e.g. test
components are not part of a module; not all source files are guaranteed to
be included), test `tsconfig` projects will now use a new `test` migration
strategy where all queries within tests are left untouched and a TODO is added.
PR Close#30034
This commit unifies the way auxillary RootScopeModule and DynamicTestModule are compiled in R3TestBed by calling `compileNgModuleDefs` explicitly for RootScopeModule. This change also resolves the problem where TestBed's code was used from the @angular/core NPM package: due to the "jit" flag, the @NgModule decorator on the RootScopeModule was transformed to RootScopeModule.decorators = [...], but actual ngModuleDef was never defined.
PR Close#30037