Martin Fink
Martin Fink

Reputation: 1931

Angular 4 - Could not resolve submodule for routing

I'm building a webapp with Angular 4. I have a top-level routing module and a separate routing module for each submodule (e.g. HomeModule).

This is my top-level routing configuration:

export const ROUTES: Routes = [
  {path: '', loadChildren: './home#HomeModule'},
  {path: '**', component: NotFoundComponent},
];

When I run ng server, I get a strange error, that module home was not found. The app does not work in the browser.

The strange part is the following: When a file is changed and webpack recompiles the project, everything works just fine and the routing works.
The error does only appear when I'm running ng serve.

This is the error I get when I'm running ng serve, not when the project is recompiled because of a file change:

ERROR in Error: Could not resolve module ./home relative to /path/to/my/project/src/app/app.module.ts
    at StaticSymbolResolver.getSymbolByModule (/path/to/my/project/node_modules/@angular/compiler/bundles/compiler.umd.js:31884:30)
    at StaticReflector.resolveExternalReference (/path/to/my/project/node_modules/@angular/compiler/bundles/compiler.umd.js:30350:62)
    at parseLazyRoute (/path/to/my/project/node_modules/@angular/compiler/bundles/compiler.umd.js:28616:55)
    at listLazyRoutes (/path/to/my/project/node_modules/@angular/compiler/bundles/compiler.umd.js:28578:36)
    at visitLazyRoute (/path/to/my/project/node_modules/@angular/compiler/bundles/compiler.umd.js:29995:47)
    at AotCompiler.listLazyRoutes (/path/to/my/project/node_modules/@angular/compiler/bundles/compiler.umd.js:29963:20)
    at AngularCompilerProgram.listLazyRoutes (/path/to/my/project/node_modules/@angular/compiler-cli/src/transformers/program.js:157:30)
    at Function.NgTools_InternalApi_NG_2.listLazyRoutes (/path/to/my/project/node_modules/@angular/compiler-cli/src/ngtools_api.js:44:36)
    at AngularCompilerPlugin._getLazyRoutesFromNgtools (/path/to/my/project/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:247:66)
    at Promise.resolve.then.then (/path/to/my/project/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:538:50)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

Thanks in advance.

Upvotes: 34

Views: 49806

Answers (9)

Zack
Zack

Reputation: 492

I had a similar problem which took days to resolve but I ended up going back to recheck the structure of each statement/path. Below is what I had before:

      {
    path: 'payments',
    loadChildren: './pages/service-payments/service-payments.module#ServicePaymentsPageModule'
  }

I then changed the path as below:

      {
    path: 'payments',
    loadChildren: '../service-payments/service-payments.module#ServicePaymentsPageModule'
  }

I hope it helps somebody in the future.

Upvotes: 0

Lucas L Jordan
Lucas L Jordan

Reputation: 101

UPDATE

As of Angular 8+ there is new syntax for lazyloading modules this is the issue I ran into looking at older code examples.

Previousely:

 const routes: Routes = [
   { path: 'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule' }
 ];

As of Angular 8+:

  const routes: Routes = [
    {
      path: 'dashboard', 
      loadChildren: () =>
        import('./dashboard/dashboard.module').then(m => m.DashboardModule)
    }
  ];

Michael Hoffmann explains here

Since Angular 8 we can use the browser’s built-in dynamic imports to load JavaScript modules asynchronous in Angular. A lazy-loaded module can be defined in the routing configuration using the new import(...) syntax for loadChildren:

Upvotes: 2

Sagar Khatri
Sagar Khatri

Reputation: 635

For those who are not able to find a solution, simply remove ".ts" extension from the loadChildren line.

 {path: '', loadChildren: './home.ts#HomeModule'},

to

{path: '', loadChildren: './home#HomeModule'},

Upvotes: 3

Wayne
Wayne

Reputation: 156

I came across this issue, for me I simply forgot to add .module to the file name.

I had this:

const routes: Routes = [
  /* ... */
  {
    path: 'page-not-found',
    loadChildren: './modules/page-not-found/page-not-found#PageNotFoundModule' // <- page-not-found missing .module
  },
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: 'page-not-found'
  }
];

Should be:

const routes: Routes = [
  /* ... */
  {
    path: 'page-not-found',
    loadChildren: './modules/page-not-found/page-not-found.module#PageNotFoundModule'
  },
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: 'page-not-found'
  }
];

Upvotes: 0

Vikash Choudhary
Vikash Choudhary

Reputation: 1609

I have faced a similar issue and resolved by removing the extension from the module name and adding a relative path.

Code which was throwing an error:

const routes: Routes = [
    {
        path: 'settings',
        loadChildren: 'app/setting/setting.module.ts#SettingsModule'
    }
];

Working code:

const routes: Routes = [
    {
        path: 'settings',
        loadChildren: './setting/setting.module#SettingsModule'
    }
];

Hope it helps!

Note: On Angular version - 7.0.0

Upvotes: 4

spottedmahn
spottedmahn

Reputation: 15981

I was using the absolute path convention: app/home#HomeModule and it wasn't working.

I then tried the relative path convention: ./home#HomeModule and it worked.

... in the CLI, the paths to lazy routes should be relative from the file you're in

Source


I followed this Tutorial and it used the absolute path convention and it worked.

Would love to know why the inconsistency...


UPDATE:

As Friedrich mentioned, to make it work using an Absolute Path, update src/tsconfig.app.json as follows:

{
  ...,
  "compilerOptions": {
    ...,
    baseUrl: "./"
  }
}

Upvotes: 82

Sksaif Uddin
Sksaif Uddin

Reputation: 692

I had the same issue and none of the answers above worked for me,the final solution i found was using the absolute path of the module and module class name after the '#'.

    export const ROUTES: Routes = [
       {path: '', loadChildren: 'src/app/pathToYourModule/home.module#HomeModule'},
       {path: '**', component: NotFoundComponent}
     ];

I started the path from 'src' and dont forget to remove the '.ts' from the module path.

Upvotes: 14

Michael Benoit
Michael Benoit

Reputation: 111

You have to remove the .ts suffix from the reference to your module file: {path: '', loadChildren: 'app/pathToYourModule/home.module#HomeModule'},

Upvotes: 10

user7332973
user7332973

Reputation:

Try using the absolute path of your module with the module file name like so:

export const ROUTES: Routes = [
  {path: '', loadChildren: 'app/pathToYourModule/home.module.ts#HomeModule'},
  {path: '**', component: NotFoundComponent},
];

Upvotes: 2

Related Questions