perf(router): use `ngDevMode` to tree-shake error messages in router (#38674)
This commit adds `ngDevMode` guard to throw some errors only in dev mode The ngDevMode flag helps to tree-shake these error messages from production builds (in dev mode everything will work as it works right now) to decrease production bundle size. PR Close #38674
This commit is contained in:
parent
281865bbcf
commit
db21c4fb44
|
@ -39,7 +39,7 @@
|
|||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 2289,
|
||||
"main-es2015": 245303,
|
||||
"main-es2015": 242351,
|
||||
"polyfills-es2015": 36938,
|
||||
"5-es2015": 751
|
||||
}
|
||||
|
@ -49,7 +49,7 @@
|
|||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime-es2015": 2289,
|
||||
"main-es2015": 221887,
|
||||
"main-es2015": 218961,
|
||||
"polyfills-es2015": 36723,
|
||||
"5-es2015": 781
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {LocationStrategy} from '@angular/common';
|
||||
import {Attribute, Directive, ElementRef, HostBinding, HostListener, Input, isDevMode, OnChanges, OnDestroy, Renderer2, SimpleChanges} from '@angular/core';
|
||||
import {Attribute, Directive, ElementRef, HostBinding, HostListener, Input, OnChanges, OnDestroy, Renderer2, SimpleChanges} from '@angular/core';
|
||||
import {Subject, Subscription} from 'rxjs';
|
||||
|
||||
import {QueryParamsHandling} from '../config';
|
||||
|
@ -206,7 +206,7 @@ export class RouterLink implements OnChanges {
|
|||
*/
|
||||
@Input()
|
||||
set preserveQueryParams(value: boolean) {
|
||||
if (isDevMode() && <any>console && <any>console.warn) {
|
||||
if ((typeof ngDevMode === 'undefined' || ngDevMode) && <any>console && <any>console.warn) {
|
||||
console.warn('preserveQueryParams is deprecated!, use queryParamsHandling instead.');
|
||||
}
|
||||
this.preserve = value;
|
||||
|
@ -342,7 +342,7 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
|||
*/
|
||||
@Input()
|
||||
set preserveQueryParams(value: boolean) {
|
||||
if (isDevMode() && <any>console && <any>console.warn) {
|
||||
if ((typeof ngDevMode === 'undefined' || ngDevMode) && <any>console && <any>console.warn) {
|
||||
console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
|
||||
}
|
||||
this.preserve = value;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {isDevMode} from '@angular/core';
|
||||
import {MonoTypeOperatorFunction} from 'rxjs';
|
||||
import {map} from 'rxjs/operators';
|
||||
|
||||
|
@ -186,7 +185,7 @@ export class ActivateRoutes {
|
|||
// Activate the outlet when it has already been instantiated
|
||||
// Otherwise it will get activated from its `ngOnInit` when instantiated
|
||||
context.outlet.activateWith(future, cmpFactoryResolver);
|
||||
} else if (isDevMode() && console && console.warn) {
|
||||
} else if ((typeof ngDevMode === 'undefined' || ngDevMode) && console && console.warn) {
|
||||
console.warn(
|
||||
`A router outlet has not been instantiated during routes activation. URL Segment: '${
|
||||
future.snapshot._urlSegment}'`);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {Location, PopStateEvent} from '@angular/common';
|
||||
import {Compiler, Injectable, Injector, isDevMode, NgModuleFactoryLoader, NgModuleRef, NgZone, Type, ɵConsole as Console} from '@angular/core';
|
||||
import {Compiler, Injectable, Injector, NgModuleFactoryLoader, NgModuleRef, NgZone, Type, ɵConsole as Console} from '@angular/core';
|
||||
import {BehaviorSubject, EMPTY, Observable, of, Subject, SubscriptionLike} from 'rxjs';
|
||||
import {catchError, filter, finalize, map, switchMap, tap} from 'rxjs/operators';
|
||||
|
||||
|
@ -1077,7 +1077,8 @@ export class Router {
|
|||
queryParamsHandling,
|
||||
preserveFragment
|
||||
} = navigationExtras;
|
||||
if (isDevMode() && preserveQueryParams && <any>console && <any>console.warn) {
|
||||
if ((typeof ngDevMode === 'undefined' || ngDevMode) && preserveQueryParams && <any>console &&
|
||||
<any>console.warn) {
|
||||
console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
|
||||
}
|
||||
const a = relativeTo || this.routerState.root;
|
||||
|
@ -1131,7 +1132,8 @@ export class Router {
|
|||
*/
|
||||
navigateByUrl(url: string|UrlTree, extras: NavigationExtras = {skipLocationChange: false}):
|
||||
Promise<boolean> {
|
||||
if (isDevMode() && this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
|
||||
if (typeof ngDevMode === 'undefined' ||
|
||||
ngDevMode && this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
|
||||
this.console.warn(
|
||||
`Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ export function provideLocationStrategy(
|
|||
}
|
||||
|
||||
export function provideForRootGuard(router: Router): any {
|
||||
if (router) {
|
||||
if ((typeof ngDevMode === 'undefined' || ngDevMode) && router) {
|
||||
throw new Error(
|
||||
`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
|
||||
}
|
||||
|
|
|
@ -20,8 +20,9 @@ export function validateConfig(config: Routes, parentPath: string = ''): void {
|
|||
}
|
||||
|
||||
function validateNode(route: Route, fullPath: string): void {
|
||||
if (!route) {
|
||||
throw new Error(`
|
||||
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
||||
if (!route) {
|
||||
throw new Error(`
|
||||
Invalid configuration of route '${fullPath}': Encountered undefined route.
|
||||
The reason might be an extra comma.
|
||||
|
||||
|
@ -32,55 +33,57 @@ function validateNode(route: Route, fullPath: string): void {
|
|||
{ path: 'detail/:id', component: HeroDetailComponent }
|
||||
];
|
||||
`);
|
||||
}
|
||||
if (Array.isArray(route)) {
|
||||
throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
|
||||
}
|
||||
if (!route.component && !route.children && !route.loadChildren &&
|
||||
(route.outlet && route.outlet !== PRIMARY_OUTLET)) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
|
||||
}
|
||||
if (route.redirectTo && route.children) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': redirectTo and children cannot be used together`);
|
||||
}
|
||||
if (route.redirectTo && route.loadChildren) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': redirectTo and loadChildren cannot be used together`);
|
||||
}
|
||||
if (route.children && route.loadChildren) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': children and loadChildren cannot be used together`);
|
||||
}
|
||||
if (route.redirectTo && route.component) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': redirectTo and component cannot be used together`);
|
||||
}
|
||||
if (route.path && route.matcher) {
|
||||
throw new Error(
|
||||
`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
|
||||
}
|
||||
if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
|
||||
}
|
||||
if (route.path === void 0 && route.matcher === void 0) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': routes must have either a path or a matcher specified`);
|
||||
}
|
||||
if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
|
||||
throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
|
||||
}
|
||||
if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
|
||||
const exp =
|
||||
`The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
||||
throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${
|
||||
route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
|
||||
}
|
||||
if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': pathMatch can only be set to 'prefix' or 'full'`);
|
||||
}
|
||||
if (Array.isArray(route)) {
|
||||
throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
|
||||
}
|
||||
if (!route.component && !route.children && !route.loadChildren &&
|
||||
(route.outlet && route.outlet !== PRIMARY_OUTLET)) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
|
||||
}
|
||||
if (route.redirectTo && route.children) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': redirectTo and children cannot be used together`);
|
||||
}
|
||||
if (route.redirectTo && route.loadChildren) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': redirectTo and loadChildren cannot be used together`);
|
||||
}
|
||||
if (route.children && route.loadChildren) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': children and loadChildren cannot be used together`);
|
||||
}
|
||||
if (route.redirectTo && route.component) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': redirectTo and component cannot be used together`);
|
||||
}
|
||||
if (route.path && route.matcher) {
|
||||
throw new Error(
|
||||
`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
|
||||
}
|
||||
if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
|
||||
}
|
||||
if (route.path === void 0 && route.matcher === void 0) {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': routes must have either a path or a matcher specified`);
|
||||
}
|
||||
if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
|
||||
throw new Error(
|
||||
`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
|
||||
}
|
||||
if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
|
||||
const exp =
|
||||
`The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
|
||||
throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${
|
||||
route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
|
||||
}
|
||||
if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
|
||||
throw new Error(`Invalid configuration of route '${
|
||||
fullPath}': pathMatch can only be set to 'prefix' or 'full'`);
|
||||
}
|
||||
}
|
||||
if (route.children) {
|
||||
validateConfig(route.children, fullPath);
|
||||
|
|
Loading…
Reference in New Issue