621 Commits

Author SHA1 Message Date
Paul Gschwendtner 349043db7b build: replace size-tracking test with rule from shared dev-infra (#46802)
The JS size-tracking logic has been moved into the dev-infra repository
and the rule has been updated to work better with Bazel labels. The
Starlark target is updated accordingly in this commit.

PR Close #46802
2022-07-12 19:06:30 +00:00
Jessica Janiuk 61c7e26500 Revert "refactor(router): Remove use of OutletInjector" (#46775)
This reverts commit e288d87742.

PR Close #46775
2022-07-11 19:13:21 +00:00
Jessica Janiuk ec267b4127 Revert "build: update router symbol golden file" (#46760)
This reverts commit bb9ec76c7d.

PR Close #46760
2022-07-08 23:12:34 +00:00
Andrew Scott 770f05421e refactor(router): Remove use of OutletInjector (#46755)
OutletInjector doesn't do anything special. Injector.create can be used instead

PR Close #46755
2022-07-08 21:56:01 +00:00
Andrew Scott 50126af513 build: update router symbol golden file (#46757)
File got out of date when merging a patch & main branch change

PR Close #46757
2022-07-08 21:14:57 +00:00
Paul Gschwendtner cde0a40a4b test: refactor bundle tests to not directly access CommonJS module.exports (#46642)
The test apps are bundled using their production ESM JS output using
`esbuild`. ESBuild warns about any CJS usages, like `module.exports.`

```
INFO: From Bundling Javascript packages/core/test/bundling/todo_i18n/index.ts [esbuild]:
▲ [WARNING] The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected

    bazel-out/k8-fastbuild/bin/packages/core/test/bundling/todo_i18n/index.mjs:494:0:
      494 │ module.exports = {
          ╵ ~~~~~~

  This file is considered to be an ECMAScript module because the file name ends in ".mjs".
```

Some bundling tests currently use `module.exports` to make
functions/symbols available to specs later requiring the bundle (in
order to run the bundle). Instead of using the CJS global here, the
logic can be attached consistently to `window` (there is currently a
mismatch of window vs. module.exports anyway..).

PR Close #46642
2022-07-01 10:20:52 -07:00
Alex Rickabaugh 368765c4a1 refactor(core): remove experimental Renderer3 abstraction (#46646)
This commit removes the `Renderer3` experiment which attempted to use the
real DOM API as Angular's renderer. As shown in the diff, having this
experiment around added real code complexity to Angular that could not be
removed by an optimizer.

Since we no longer feel this experiment is worth continuing, we're removing
the `Renderer3` concept and all supporting code.

PR Close #46646
2022-06-30 12:44:30 -07:00
Alex Rickabaugh 4272da5de6 refactor(core): disable automatic usage of Renderer3 (#46646)
Previously, when instantiating a component, Angular would look in the DI
hierarchy for `RendererFactory2`. Any DI tree which rolls up through an
application injector (that is, one created with `BrowserModule`) should be
able to provide this interface. If not found, Angular would switch to the
experimental `Renderer3` mechanism. This switch was designed this way,
because it allowed for the creation of experimental applications where
`RendererFactory2` was not included in the bundle at all.

In this commit, instead of automatically falling back on `Renderer3`-style
rendering, an error is raised instead if `RendererFactory2` is missing from
the DI hierarchy.

PR Close #46646
2022-06-30 12:44:30 -07:00
Alan Agius 72976c7a28 test: update golden symbols (#46582)
This is causing CI to fail

PR Close #46582
2022-06-29 00:53:52 -07:00
Alex Rickabaugh 0a36ee70fc test(core): convert remaining bundling tests to not use renderComponent (#46559)
This commit converts the remaining bundling tests which were using
`renderComponent` to use regular bootstrapping instead.

Since `renderComponent` is synchronous and regular bootstrapping is not,
some test adjustments were necessary to wait for bootstrapping before test
assertions could run.

Additionally, debug servers were adjusted in some cases where they'd broken
(likely some time ago).

PR Close #46559
2022-06-28 21:37:46 -07:00
Alex Rickabaugh 290ccc36c7 test(core): add symbol tests back to todo, hello_world bundling tests (#46559)
The deleted r3 versions of these tests had symbol tests, but their r2
equivalents did not. This commit adds symbol tests to the r2 variants.

PR Close #46559
2022-06-28 21:37:46 -07:00
Alex Rickabaugh 5e4be235ca test(core): rename r2-based hello_world and todo bundling tests (#46559)
In the previous commit, the r3-based hello_world and todo tests were deleted
in favor of the r2 versions. This commit renames the r2 versions to drop the
r2 suffix.

PR Close #46559
2022-06-28 21:37:46 -07:00
Alex Rickabaugh 5b84168ee8 test(core): remove redundant renderComponent-based bundling tests (#46559)
The `hello_world` and `todo` bundling tests use the experimental
`renderComponent` function (and `Renderer3`) as a result, and have
corresponding `Renderer2` equivalents. This commit removes these tests in
favor of the `Renderer2` versions, which will be renamed in a future commit.

PR Close #46559
2022-06-28 21:37:46 -07:00
Andrew Kushnir 1e7f22f00a fix(core): trigger ApplicationRef.destroy when Platform is destroyed (#46497)
This commit updates the `ApplicationRef` logic to trigger the destroy operation when an underlying platform is destroyed. This is needed to make sure all teardown processing is completed correctly to avoid memory leaks.

Closes #46473.

PR Close #46497
2022-06-28 13:02:56 -07:00
Dylan Hunn 747872212d fix(forms): Update a Forms validator error to use RuntimeError (#46537)
Replace `new Error()` in a forms Validators function with `RuntimeError`, for better tree-shakability. Also, improve the error messages, and add documentation.

PR Close #46537
2022-06-28 11:32:55 -07:00
Alex Rickabaugh 35f14c6296 refactor(core): disable renderer3 unless explicitly enabled by tests (#46530)
The `Renderer3` abstraction in Angular was an experimental code path in Ivy
which uses direct DOM operations instead of the former `Renderer2` path. To
allow `Renderer2` to tree-shake away, `Renderer3` is the default _unless_
`Renderer2` is provided. It was only an experiment, and never meant to be a
production code path.

However, it's possible for `Renderer3` to leak into user code. This commit
prevents that possibility by causing the `Renderer3` path to throw, unless
an explicit function has been called to enable it.

PR Close #46530
2022-06-28 11:15:55 -07:00
Andrew Scott ca043987c8 refactor(router): separate router initializer into different logical providers (#46481)
This change separates the router initializer into different providers.
While it does not actually change the tree-shakeablity or the public
API, it does move us towards a world that _could_ do this. That is,
instead of `initialNavigation: 'disabled'`, users could use
`provideDisabledInitialNavigation` in the `bootstrapApplication` call
and none of the code for `initialNavigation: 'enabledBlocking'` would be
included in the application.

PR Close #46481
2022-06-27 09:07:13 -07:00
Andrew Scott 464d4133cb refactor(router): Move preloading to tree-shakeable provider (#46481)
Extracting preloading to a provider moves us towards
thinking about a world where `ExtraOptions` doesn't exist to control
behaviors that are opt-in/opt-out. Instead, these behaviors could be
controlled by the presence (or lackthereof) of the providers which has
the functionality. This is relevant to a world in which we no longer
have the `RouterModule` but instead have something like `provideRouter`
where the features are tree-shakeable.

This change _does not_ make the `RouterPreloader` tree-shakeable inside
`RouterModule.forRoot` because the compiler cannot statically determine
whether it's needed. However, in the `provideRouter` world without
`forRoot`, preloading could be exposed through the provider function
instead, making the `RouterPreloader` and `PreloadingStrategy`
implementations tree-shakeable for those that don't use it (which is the
default - no preloading).

PR Close #46481
2022-06-27 09:07:13 -07:00
Andrew Scott 77ae8e1c20 refactor(router): clean up internal hooks (#46321)
* beforePreactivation hook is unused
* The only place that uses afterPreactivation does not use the arguments

Not to say we won't want to provide hooks similar to this in the future,
but the current state is over-engineered for what it's being used for.

PR Close #46321
2022-06-10 15:23:57 +00:00
Dylan Hunn dde0b7f4b3 fix(forms): allow FormBuilder.group(...) to accept optional fields. (#46253)
Consider the case in which `FormBuilder` is used to construct a group with an optional field:

```
const controls = { name: fb.control('') };
const foo: FormGroup<{
  name: FormControl<string | null>;
  address?: FormControl<string | null>;
}> = fb.group<{
  name: FormControl<string | null>;
  address?: FormControl<string | null>;
}>(controls);
```

Today, with fully strict TypeScript settings, the above will not compile:

```
Types of property 'controls' are incompatible.
Type '{ name: FormControl<string | null>; address?: FormControl<FormGroup<SubFormControls> | null | undefined> | undefined; }' is not assignable to type '{ name: FormControl<string | null>; address?: FormGroup<SubFormControls> | undefined; }'.
```

Notice that the `fb.group(...)` is calculating the following type for address: `address?: FormControl<FormGroup<string|null>`. This is clearly wrong -- an extraneous `FormControl` has been added!

This is coming from the calculation of the result type of `fb.group(...)`. In the type definition, if we cannot detect the outer control type, [we assume it's just an unwrapped value, and automatically wrap it in `FormControl`](https://github.com/angular/angular/blob/14.0.0/packages/forms/src/form_builder.ts#L66).

Because the optional `{address?: FormControl<string|null>}` implicitly makes the RHS have type `FormControl<string|null>|undefined`, [the relevant condition is not satisfied](https://github.com/angular/angular/blob/14.0.0/packages/forms/src/form_builder.ts#L55). In particular, the condition expects just `FormGroup<T>`, not `FormGroup<T>|undefined`. So we assume `T` is a value type, and it gets wrapped with `FormControl`.

The solution is to add the cases where `undefined` is included in the union type when detecting which control `T` is (if any).

PR Close #46253
2022-06-06 10:14:20 -07:00
Kristiyan Kostadinov b497aa0cf7 refactor(core): minor ComponentDef improvements (#46093)
Makes the following improvements in the runtime:
* Uses the unique ID of the component definition to keep track of its injector in the `StandaloneFeature`, instead of the definition itself. This reduces the amount of memory we can leak, if something doesn't get cleaned up.
* Changes the naming and description of the `ComponentDef.id` to reflect what it is used for.

PR Close #46093
2022-06-02 13:41:28 -07:00
Kristiyan Kostadinov 19b4cc969d refactor(core): remove unused error handler logic (#46216)
There's some old logic in the error handler that tries to read an `ngErrorHandler` property off of the errors that are being logged. As far as I can tell, this is a ViewEngine leftover and it isn't actually being used anywhere.

PR Close #46216
2022-06-02 13:40:17 -07:00
Andrew Kushnir 51baa0b448 docs(core): improve inject function docs (#46168)
This commit updates the `inject` function docs by:
- rephrasing a description to include more usage cases
- adding usage examples
- making a function itself a public API (vs its alias const that was used previously)

PR Close #46168
2022-05-31 13:55:15 -07:00
Andrew Kushnir 5e71f2abc0 refactor(core): tree-shake away a DI error message string in prod bundles (#45994)
This commit adds the `ngDevMode` check to tree-shake away an error message string (which also retains a reference to an extra function).

PR Close #45994
2022-05-16 10:04:57 -07:00
Andrew Scott 77c9508e51 refactor(router): Only create the Route injector when the path matches (#45990)
Currently, the `Router` will create the `EnvironmentInjector` for a
`Route` with `providers` as soon as it _attempts_ to match segments to
the `Route`. Instead, this change updates the logic to only create the
injector once we have confirmed that the `Route` matches. Note that this
will include partial matches where the final navigation still fails with
a "cannot match any routes to segment" error. We need to maintain the
injector hierarchy so we still need to create parent injectors before
descending into the child routes and determining if there is a full
match or just a partial one.

resolves #45988

PR Close #45990
2022-05-13 12:19:16 -07:00
Alex Rickabaugh 3f7ecec59b fix(core): set correct context for inject() for component ctors (#45991)
The `inject()` function was introduced with Ivy to support imperative
injection in factory/constructor contexts, such as directive or service
constructors as well as factory functions defined in `@Injectable` or
`InjectionToken`. However, `inject()` in a component/directive constructor
did not work due to a flaw in the logic for creating the internal factory
for components/directives.

The original intention of this logic was to keep `ɵɵdirectiveInject` tree-
shakable for applications which don't use any component-level DI. However,
this breaks the `inject()` functionality for component/directive
constructors.

This commit fixes that issue and adds tests for all the various cases in
which `inject()` should function. As a result `ɵɵdirectiveInject` is no
longer tree-shakable, but that's totally acceptable as any application that
uses `*ngIf` or `*ngFor` already contains this function. It's possible to
change how `inject()` works to restore this tree-shakability if needed.

PR Close #45991
2022-05-13 11:57:44 -07:00
Andrew Kushnir 23c4c9601e perf(platform-browser): avoid including Testability by default in bootstrapApplication (#45885)
The Testability-related logic was refactored in https://github.com/angular/angular/pull/45657 to become tree-shaking-friendly: it was decoupled from the core providers of the `BrowserModule`. This commit updates the newly-introduced `bootstrapApplication` function to exclude Testability-providers by default (note: the Testability is still included in the NgModule-based bootstrap).

In order to add the Testability to the app bootstrapped via `bootstrapApplication`, the `provideProtractorTestingSupport` function is introduced.

PR Close #45885
2022-05-10 13:34:29 -07:00
JoostK e9317aee71 perf(core): allow checkNoChanges mode to be tree-shaken in production (#45913)
This commit guards all logic that exists for the `checkNoChanges` mode
with `ngDevMode` checks such that the logic can be tree-shaken.

PR Close #45913
2022-05-09 12:04:04 -07:00
Andrew Kushnir 40bf2a6a81 refactor(core): make Testability compatible with tree-shaking (#45657)
This commit refactors the `Testability`-related logic to extract the necessary providers into a separate array, so that it can later become it's own NgModule (or exposed as an array of providers) and be excluded from the new APIs by default.

PR Close #45657
2022-05-05 11:50:23 -07:00
Dylan Hunn 2dbdebc646 feat(forms): Add FormBuilder.nonNullable. (#45852)
With typed forms, all `FormControl`s are nullable by default, because they can be reset to `null`. This behavior is possible to change by passing the option `initialValueIsDefault: true`. However, in a large form, this is extremely cumbersome, as the option must be repeated over and over. Additionally, it is not possible to take full advantage of `FormBuilder`, since `FormBuilder.group` and `FormBuilder.array` will produce nullable controls.

This PR introduces a new accessor `FormBuilder.nonNullable`, which produces *non-nullable* controls. Specifically, any call to `.control` will produce controls with `{initialValueIsDefault: true}`, and calls to `.array` or `.group` that implicitly build inner controls will have the same effect.

```ts
let nfb = new FormBuilder().nonNullable;
let name = nfb.group({who: 'Alex'}); // FormGroup<{who: FormControl<string>}>
name.reset();
console.log(name); // {who: 'Alex'}
```

PR Close #45852
2022-05-04 12:46:05 -07:00
Andrew Kushnir fa755b2a54 fix(core): prevent BrowserModule providers from being loaded twice (#45826)
This commit updates the logic of the `BrowserModule` to detect a situation when it's used in the `bootstrapApplication` case, which already includes `BrowserModule` providers.

PR Close #45826
2022-05-03 16:08:04 -07:00
Pawel Kozlowski 410d81f0e2 refactor(core): disallow standalone components in importProvidersFrom calls (#45837)
This commit narrows down acceptable argument types of the
`importProvidersFrom` function. More specifically, it rejects
standalone components as a source of imports.

PR Close #45837
2022-05-03 13:12:36 -07:00
Alex Rickabaugh d322052db3 refactor(core): guard against importProvidersFrom in components (#45838)
`importProvidersFrom` provides a bridge from the world of NgModule-based DI
configuration to the new, "standalone" world of direct providers and
environment injectors. Early user feedback suggested some confusion around
where this function was supposed to be used, particularly around importing
NgModule-based providers into standalone component `providers` arrays, which
is not the intended use. This confusion is exacerbated by the fact that due
to the unified `Provider` type, this kind of misconfiguration was happily
accepted by the type system.

This commit changes the return type of `importProvidersFrom` to wrap the
returned providers in an opaque type that prevents them from being used in
component provider contexts. This, together with stronger documentation
around the purpose and functionality of `importProvidersFrom`, should
address some of the above confusion.

PR Close #45838
2022-05-02 15:50:44 -07:00
Andrew Kushnir ad5ffffc7b refactor(core): rename INJECTOR_INITIALIZER -> ENVIRONMENT_INITIALIZER (#45845)
This commit renames the `INJECTOR_INITIALIZER` to `ENVIRONMENT_INITIALIZER` to better represent the intention of the token.

PR Close #45845
2022-05-02 15:02:06 -07:00
Alex Rickabaugh 882f595a13 refactor(core): support ModuleWithProviders directly in importProvidersFrom (#45722)
There were two problems with the `importProvidersFrom` function related to
`ModuleWithProviders` values:

* The public type did not accept `ModuleWithProviders` values directly.
* The implementation of `walkProviderTree` delegates collection of MWP providers
  to its caller, in order for the ordering of such providers to be correct.
  However, `importProvidersFrom` was not performing that collection, causing MWP
  providers passed in at the top level to be dropped.

PR Close #45722
2022-04-27 09:05:51 -07:00
Andrew Scott 50004c143b feat(router): Support lazy loading standalone components with loadComponent (#45705)
Similarly to the symmetry being strengthened between children and loadChildren,
a new loadComponent property will be introduced as the asynchronous version of component.
This will allow for direct single-component lazy loading:

```
{path: 'lazy/a', loadComponent:
  () => import('./lazy/a.component').then(m => m.ACmp)},
{path: 'lazy/b', loadComponent:
  () => import('./lazy/b.component').then(m => m.BCmp)},
```

This option requires that the component being loaded is standalone and
is implemented as a runtime check.

Other notes:
* Components are not loaded until all guards and resolvers complete.
* Loading the component is included in the function passed to the router
  preloading strategy
* `RouteConfigLoadStart` and `RouteConfigLoadEnd` events emit at the
  start and end of the component loading
* `CanLoad` guards _do not_ apply to `loadComponent`. `canActivate`
  should be used instead, just like you would do if it were simply
  `component` instead.

PR Close #45705
2022-04-25 09:39:44 -07:00
Andrew Kushnir 3e46a426c4 test(core): add integration test apps for the bootstrapApplication API (#45674)
This commit adds 2 integration apps to verify the `bootstrapApplication` API behavior as well as keep track of the bundle size and retained symbols (tree-shaking).

PR Close #45674
2022-04-21 17:47:54 -07:00
Andrew Kushnir 5771b18a98 feat(core): add the bootstrapApplication function (#45674)
This commit implements the `bootstrapApplication` function that allows bootstrapping an application and pass a standalone component as a root component.

PR Close #45674
2022-04-21 17:47:54 -07:00
Paul Gschwendtner a50e2da64a fix(localize): ensure transitively loaded compiler code is tree-shakable (#45405)
The localize primary entry-point (used at runtime in application code)
indirectly loads from the compiler package for computing message ids.
The compiler package has a couple of constants which cannot be DCE-ded/
tree-shaken due to side-effect reliance that is detected by Terser.

We fix these constants to be three-shakable. Note that another issue
technically would be that the compiler package has a side-effect call
for `publishFacade` (for JIT), but that invocation is marked as pure by
the Angular CLI babel optimization pipeline. So this results is no
unused code currently but is risky and should be addressed in the future.

PR Close #45405
2022-04-21 11:09:39 -07:00
Alex Rickabaugh 9f795134fa refactor(core): support standalone components in importProvidersFrom (#45687)
This commit refactors `importProvidersFrom` to support pulling providers
from the dependencies of a standalone component, in addition to NgModules.
Tests will be added in a future commit when standalone components can be
created without calling private APIs.

PR Close #45687
2022-04-20 16:01:55 -07:00
Alex Rickabaugh bb6e11c7e4 refactor(compiler-cli): reorganize importProvidersFrom to avoid cycles (#45687)
This commit extracts the `importProvidersFrom` function and associated
machinery into a separate file, as opposed to being colocated with
`R3Injector`. Separating these functions will mitigate potential future
circular dependencies as `importProvidersFrom` starts being used in
different parts of the codebase.

PR Close #45687
2022-04-20 16:01:55 -07:00
Andrew Scott 4e0957a4e1 feat(router): Add ability to specify providers on a Route (#45673)
Currently, the only way to specify new providers for a `Route` and the
children is to create a new `NgModule` with those providers and use the
`loadChildren` feature. This is pretty confusing and a wholly indirect
way of accomplishing this task. With this commit, developers will be
able to specify a list of providers directly on the `Route` itself.
These providers will apply the that route and its children.

This feature was inspired by the upcoming standalone components feature.
This ties in there because, as mentioned before, the prior art for lazy
loading configs was to load an `NgModule`. This loaded module contained
new route configs _and_ could specify new providers. Separating those
two concepts, there should be a way to load _just_ some new routes, but
there should also be a way to specify new providers as well (something
you could do in the `NgModule` world and now will be able to do in the
world without any `NgModule` through this feature).

PR Close #45673
2022-04-20 11:32:07 -07:00
Alex Rickabaugh 1527e8f4c0 refactor(core): change component emit to 'dependencies' (#45672)
Previously, the compiler would represent template dependencies of a
component in its component definition through separate fields (`directives`,
`pipes`).

This commit refactors the compiler/runtime interface to use a single field
(`dependencies`). The runtime component definition object still has separate
`directiveDefs` and `pipeDefs`, which are calculated from the `dependencies`
when the definition is evaluated.

This change is also reflected in partially compiled declarations. To ensure
compatibility with partially compiled code already on NPM, the linker
will still honor the old form of declaration (with separate fields).

PR Close #45672
2022-04-20 05:45:56 -07:00
Andrew Scott ea8256f43d refactor(router): Move config loader tracking to the RouterConfigLoader (#45656)
This wasn't exactly possible before because the `RouterConfigLoader` was
not an Injectable so there wasn't a straightforward way to share
information between `ApplyRedirects` and the preloader. They each had
their own implementation so they needed to store the values on the
`Route` so they both had access to them. I imagine this was the case
because trying to inject `Router` (to get access to the events) into the
preloader would have caused a circular dependency.

This refactor co-locates the loading details with the loader itself
rather than leaking implementation into the public route config and
mutating the object in an awkward way. This also promotes
`RouterConfigLoader` to a proper `Injectable` so data can be shared
throughout the system.

PR Close #45656
2022-04-18 16:05:45 -07:00
Andrew Scott eb7661c072 refactor(router): unbundle the lazy loaded routes from the lazy loaded module injector (#45593)
In the standalone world, these concepts will no longer be one and the
same. You can load routes without them being inside an `NgModule` with
`RouterModule.forChild`. In addition, routes will be able to define
their own providers, which will be included in an injector that is not
necessarily lazy loaded.

PR Close #45593
2022-04-18 09:52:56 -07:00
Alex Rickabaugh d5a6cd1111 feat(core): implement EnvironmentInjector with adapter to NgModuleRef (#45626)
This commit exposes a new `EnvironmentInjector` abstraction, which
generalizes the "module injector" concept to injectors that are not based on
NgModules.

An EnvironmentInjector is a conceptual analogue of an `NgModuleRef` - it
represents an injector on the former "module" DI hierarchy in Angular (now
renamed to the "environment injector hierarchy"). Environment injectors are
created via the `createEnvironmentInjector` function from a list of
`Provider`s.

For backwards compatibility with current code using `NgModuleRef`,
`EnvironmentInjector`s are wrapped by an adapter `NgModuleRef`
implementation, so injecting `NgModuleRef` always returns the latest
`EnvironmentInjector`, even if that injector was not based on an NgModule.
Conversely, NgModule-based `NgModuleRef`s created via `createNgModuleRef`
are _also_ `EnvironmentInjector`s.

PR Close #45626
2022-04-18 09:28:42 -07:00
Andrew Kushnir b568a5e708 feat(core): implement importProvidersFrom function (#45626)
This commit implements the `importProvidersFrom` function that allows
extracting a list of `Provider`s from a list of NgModule types. The
R3Injector which implements DI at the "module" level for Angular is
refactored to use this functionality under the hood.

This commit also implements `INJECTOR_INITIALIZER`, a DI multi-provider
token which is used to run initialization logic when an injector is created.

PR Close #45626
2022-04-18 09:28:42 -07:00
Andrew Scott 96fd29c6d2 fix(router): validate lazy loaded configs (#45526)
Lazy loaded configs are not validated at runtime like the initial set of
routes are. This change also validates lazy loaded configs right after
they're loaded.

BREAKING CHANGE: Lazy loaded configs are now also validated once loaded like the
initial set of routes are. Lazy loaded modules which have invalid Route
configs will now error. Note that this is only done in dev mode so
there is no production impact of this change.

Fixes #25431

PR Close #45526
2022-04-15 12:30:44 -07:00
Dmitrij Kuba f13295f3a3 perf(router): cancel the navigation instantly if at least one resolver doesn't emit any value (#45621)
Recently the navigation was on hold even at least one resolver didn't emit any value and completed, but another ones still are in progress to resolve any value. The changes cancel the navigation instantly if at least one resolver doesn't emit any value and completed.

PR Close #45621
2022-04-15 10:06:26 -07:00
Andrew Scott 000363eec5 refactor(router): combine functions for getting loaded config (#45613)
There are two functions which do the same thing and are meant to search
for the closest loaded config in the `ActivatedRouteSnapshot` parent
tree. These can be combined to reduce code duplication.

One difference in the current implementation is the early exit for the
implementation in `activate_routes` when `route.component` is defined.
This early exit takes advantage of the fact that the component must then
also have a `RouterOutlet`, which injects `ComponentFactoryResolver`,
which would end up being the same one as what would be found if we
continued to look up the parent tree. This is only a tiny optimization
that will actually break when we add `providers` as a feature to the
`Route` config. In this scenario, we _must_ find the correct injector
in the parent routes and cannot rely on a parent `RouterOutlet` since
there may be some route with a providers list in between.

PR Close #45613
2022-04-13 17:29:42 -07:00