I recently completed development on a new Angular application that utilizes lazy loading for improved performance.
During local testing using ng serve
(or ng serve --prod
to mimic production mode), the app compiled without errors and functioned properly. I was able to navigate seamlessly between eager loaded modules and lazy loaded ones without encountering any issues.
THE ISSUE:
However, when I built the app for production using ng build --prod
and deployed it on the server, I encountered a problem. I could not navigate from the default eager loaded module (the homepage) to a lazy loaded module.
ERROR STACK
The console displayed the following errors:
Error:
ERROR Error: Uncaught (in promise): Error: Cannot enable prod mode after platform setup. Error: Cannot enable prod mode after platform setup.
This error occurred when… attempting to navigate to any lazy loaded module for the first time
Error:
ERROR Error: Uncaught (in promise): Error: Cannot find 'LazyModule' in './lazy/lazy.module' Error: Cannot find 'LazyModule' in './lazy/lazy.module'
This error occurred when… trying to navigate to a lazy loaded component again, after encountering the first error
An interesting observation is that these errors did not result in a 404 not found status, but rather seemed to be "normal" Angular errors.
MY CODE:
Project structure
app.module.ts (& app.routing.ts)
|__lazy.module.ts (& lazymodule.routing.ts)
|__admin.module.ts (& admin.routing.ts)
app.routing.ts
// ... imports …
const appRoutes: Routes = [
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full',
},
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthGuard]
},
{
path: 'lazy',
loadChildren: "./lazy/lazy.module#LazyModule",
canLoad: [AuthGuard]
},
{
path: 'admin',
loadChildren: "./admin/admin.module#AdminModule",
canLoad: [AuthGuard]
},
{ path: '**', redirectTo: '/dashboard', canActivate: [AuthGuard] }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes, { preloadingStrategy: SelectiveStrategy, useHash:true });
selective.strategy.ts
// ... imports ...
@Injectable()
export class SelectiveStrategy implements PreloadingStrategy {
preload(route: Route, load: Function): Observable<any> {
if (route.data && route.data['preload']) {
return load();
}
return Observable.of(null);
}
}
lazymodule.routing.ts
const routes: Routes = [
{ path: '', component: FooComponent, canActivate: [AuthGuard] },
{
path: 'foo',
component: FooComponent,
canActivate: [AuthGuard]
},
{
path: 'new',
component: NewElementComponent,
canActivate: [AuthGuard]
},
{ path: '**', redirectTo: '/dashboard', canActivate: [AuthGuard] }
];
export const routing: ModuleWithProviders = RouterModule.forChild(routes);
VERSIONS:
Server: Windows Server 2012 R2
IIS Version: 8.5.9600.16384
Angular/common Version: 6.1.5
Angular & Angular-CLI Versions: 6.1.4
MY ATTEMPTS TO FIX:
1) Successfully tested locally by executing ng build --prod
.
2) Unable to resolve issue even when running locally with ng serve --prod
.
3) Added useHash:true
option in the RouterModule.forRoot
of app.routing.ts
, but no luck.
4) Moved the routing logic into the app.module.ts
file, which also did not work.
5) Tried using a root relative path like
src/app/lazy/lazy.module#LazyModule
, still unsuccessful.
6) Attempted to deploy files generated by
ng serve --prod
on the server folder, but no success.
7) Updated all npm packages, but issue persisted.
What could be causing this problem? Is it related to the code implementation or perhaps an issue with the server configuration?
Let me know if you need more information or specific sections of the code.