feat(router): throw a helpful error when misusing forRoot() from a lazy module. (#10996)
This commit is contained in:
parent
c02325dd06
commit
5ddecb18a7
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {APP_BASE_HREF, HashLocationStrategy, Location, LocationStrategy, PathLocationStrategy, PlatformLocation} from '@angular/common';
|
||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, ApplicationRef, Compiler, Inject, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, OpaqueToken, Optional, SystemJsNgModuleLoader} from '@angular/core';
|
||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, ApplicationRef, BaseException, Compiler, Inject, Injector, ModuleWithProviders, NgModule, NgModuleFactoryLoader, OpaqueToken, Optional, SkipSelf, SystemJsNgModuleLoader} from '@angular/core';
|
||||
|
||||
import {Route, Routes} from './config';
|
||||
import {RouterLink, RouterLinkWithHref} from './directives/router_link';
|
||||
|
@ -32,6 +32,8 @@ export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref,
|
|||
*/
|
||||
export const ROUTER_CONFIGURATION = new OpaqueToken('ROUTER_CONFIGURATION');
|
||||
|
||||
export const ROUTER_FORROOT_GUARD = new OpaqueToken('ROUTER_FORROOT_GUARD');
|
||||
|
||||
const pathLocationStrategy = {
|
||||
provide: LocationStrategy,
|
||||
useClass: PathLocationStrategy
|
||||
|
@ -81,11 +83,17 @@ export const ROUTER_PROVIDERS: any[] = [
|
|||
*/
|
||||
@NgModule({declarations: ROUTER_DIRECTIVES, exports: ROUTER_DIRECTIVES})
|
||||
export class RouterModule {
|
||||
constructor(@Optional() @Inject(ROUTER_FORROOT_GUARD) guard: any) {}
|
||||
|
||||
static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
|
||||
return {
|
||||
ngModule: RouterModule,
|
||||
providers: [
|
||||
ROUTER_PROVIDERS, provideRoutes(routes),
|
||||
ROUTER_PROVIDERS, provideRoutes(routes), {
|
||||
provide: ROUTER_FORROOT_GUARD,
|
||||
useFactory: provideForRootGuard,
|
||||
deps: [[Router, new Optional(), new SkipSelf()]]
|
||||
},
|
||||
{provide: ROUTER_CONFIGURATION, useValue: config ? config : {}}, {
|
||||
provide: LocationStrategy,
|
||||
useFactory: provideLocationStrategy,
|
||||
|
@ -109,6 +117,14 @@ export function provideLocationStrategy(
|
|||
new PathLocationStrategy(platformLocationStrategy, baseHref);
|
||||
}
|
||||
|
||||
export function provideForRootGuard(router: Router): any {
|
||||
if (router) {
|
||||
throw new BaseException(
|
||||
`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
|
||||
}
|
||||
return 'guarded';
|
||||
}
|
||||
|
||||
/**
|
||||
* @stable
|
||||
*/
|
||||
|
|
|
@ -1411,7 +1411,34 @@ describe('Integration', () => {
|
|||
expect(fixture.debugElement.nativeElement)
|
||||
.toHaveText('lazy-loaded-parent [lazy-loaded-child]');
|
||||
})));
|
||||
it('throws an error when forRoot() is used in a lazy context',
|
||||
fakeAsync(inject(
|
||||
[Router, Location, NgModuleFactoryLoader],
|
||||
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
|
||||
@Component({selector: 'lazy', template: 'should not show'})
|
||||
class LazyLoadedComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [LazyLoadedComponent],
|
||||
imports: [RouterModule.forRoot([{path: 'loaded', component: LazyLoadedComponent}])]
|
||||
})
|
||||
class LoadedModule {
|
||||
}
|
||||
|
||||
loader.stubbedModules = {expected: LoadedModule};
|
||||
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
|
||||
router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]);
|
||||
|
||||
let recordedError: any = null;
|
||||
router.navigateByUrl('/lazy/loaded').catch(err => recordedError = err);
|
||||
advance(fixture);
|
||||
expect(recordedError.message)
|
||||
.toEqual(
|
||||
`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
|
||||
})));
|
||||
it('should combine routes from multiple modules into a single configuration',
|
||||
fakeAsync(inject(
|
||||
[Router, Location, NgModuleFactoryLoader],
|
||||
|
|
|
@ -239,6 +239,7 @@ export declare class RouterLinkWithHref implements OnChanges, OnDestroy {
|
|||
|
||||
/** @stable */
|
||||
export declare class RouterModule {
|
||||
constructor(guard: any);
|
||||
static forChild(routes: Routes): ModuleWithProviders;
|
||||
static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue