live2learn
live2learn

Reputation: 45

Angular lazy loading cannot find module weird issue

first time posting here :)

I'm having a strange issue with Angular application. First, I'll post some code I'm using.

This is my app-routing.module.ts:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from './account/_guards/auth.guard';
import { ModulesModule } from './modules/modules.module'

const routes: Routes = [
   { path: '', loadChildren: () => ModulesModule, canActivate: [AuthGuard] },
   { path: 'account', loadChildren: './account/account.module#AccountModule' },
   { path: '**', redirectTo: '' }
];

@NgModule({
   imports: [RouterModule.forRoot(routes)],
   exports: [RouterModule]
})
export class AppRoutingModule { }

This is my app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AngularMaterialModule } from './angular-material.module';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { JwtInterceptor } from './account/_helpers/jwt.interceptor';
import { ErrorInterceptor } from './account/_helpers/error.interceptor';
import { AlertComponent } from './account/_components/alert.component';

@NgModule({
   declarations: [
      AppComponent, AlertComponent
   ],
   imports: [
      BrowserModule,
      AppRoutingModule,
      BrowserAnimationsModule,
      AngularMaterialModule,
      HttpClientModule
   ],
   providers: [
      HttpClientModule,
      { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
      { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
   ],
   bootstrap: [AppComponent]
})
export class AppModule { }

This is my modules.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AngularMaterialModule } from '../angular-material.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { ModulesRoutingModule } from './modules-routing.module';
import { HomeComponent } from './home/home.component';



@NgModule({
   declarations: [
      HomeComponent
   ],
   imports: [
      CommonModule,
      ModulesRoutingModule,
      AngularMaterialModule,
      FormsModule,
      ReactiveFormsModule,
      HttpClientModule,
   ]
})
export class ModulesModule { }

And this is my modules-routing.module.ts:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';

const routes: Routes = [
    { path: '', component: HomeComponent }
]

@NgModule({
    imports: [RouterModule.forChild(routes)],
    exports: [RouterModule]
})

export class ModulesRoutingModule { }

Now, I'm trying to do lazy loading, but here's what I'm experiencing. When I do "ng s", application starts with error: Error: Cannot find module './modules/modules.module'

But if I change as much as a blank space in app-routing.module.ts and save that change, when application reloads (on save change), it routes to the component it should route in the first place (I have auth guard implemented, so it routes to login page, as it should when I start the app). I tried googling alot, but couldn't find an explanation for the routing when something changes in app-routing. These are devDependencies:

"devDependencies": {
    "@angular-devkit/build-angular": "~0.803.19",
    "@angular/cli": "~8.3.19",
    "@angular/compiler-cli": "~8.2.14",
    "@angular/language-service": "~8.2.14",
    "@types/node": "~8.9.4",
    "@types/jasmine": "~3.3.8",
    "@types/jasminewd2": "~2.0.3",
    "codelyzer": "^5.0.0",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.1.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "~5.4.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.15.0",
    "typescript": "~3.5.3"
  }

I tried with different path for the modules.module in app-routing.module.ts, but none of that solves the problem. If you guys need more code or data, please let me know and I'll edit the question. Hope you'll have something good for me. Thanks.

Upvotes: 0

Views: 1225

Answers (3)

German Quinteros
German Quinteros

Reputation: 1930

I think you import of the ModulesModule is wrong. Try importing like this:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from './account/_guards/auth.guard';
import { ModulesModule } from './modules/modules.module'

const routes: Routes = [
   { path: '', loadChildren: () => import('./modules/Modules.module').then(mod => mod.ModulesModule), canActivate: [AuthGuard] },
   { path: 'account', loadChildren: './account/account.module#AccountModule' },
   { path: '**', redirectTo: '' }
];

@NgModule({
   imports: [RouterModule.forRoot(routes)],
   exports: [RouterModule]
})
export class AppRoutingModule { }

If it doesn't work, try to import the ModulesModule in the same way you import the AccountModule.

Upvotes: 1

Sergey
Sergey

Reputation: 7682

Try to replace { path: '', loadChildren: () => ModulesModule, canActivate: [AuthGuard] } with something more suitable. For exammple { path: '', component: SomeComponent, canActivate: [AuthGuard] }.

The syntax loadChildren: () => ModulesModule looks wrong.

There is no need to lazy load a root path which will be accessed with 90% of chance. But still if you need it it's worth changing the syntax to the correct one.

loadChildren: () => import('./module/module.module').then(m => m.ModuleModule)

This is a new better syntax introduced with Angular 8.

Here import('./module/module.module') is a regular WebPack's dynamic import which allows IDE to help you with route declaration autocompletion and checking. Then you simply return ModuleModule from loaded package (more details in webpack's docs).

Here is an example from official Angular docs regarding lazy loading.

Also, you could stop your server and try to execute ng build --prod. Most of the times it reveals many hidden errors which do not occur during default dev builds.

Upvotes: 1

t3x4r
t3x4r

Reputation: 19

Dont you need to import your modules.module in app.module?

Upvotes: 0

Related Questions