Closed areijngoudt closed 7 years ago
You should not import InfoModule nowhere else. Only reference in routes' loadChildren
When ommitting the import in app.modules, an error occurrs that route info is unknown. I'm using the angular-cli webpack version btw.
If you import your InfoModule into app.module.ts then, you will not be using LazyLoad. Your module will be compile as main part of your app.
Could you please post your info.routing.ts?
info.routing.ts:
import { ModuleWithProviders } from '@angular/core';
import { RouterModule } from '@angular/router';
import { InfoComponent } from './info.component';
const ROUTES = [
{ path: '', component: InfoComponent}
];
export const routing: ModuleWithProviders = RouterModule.forChild(ROUTES);
I could not find anything unusual in your code. I recreated a sample with your code and works fine for me. Your ROUTES const should has a type def, but even without a type def, routing works fine in my test.
Try this, just as best practice: import { ModuleWithProviders } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { InfoComponent } from './info.component';
const ROUTES: Routes = [ { path: '', component: InfoComponent} ]; export const routing: ModuleWithProviders = RouterModule.forChild(ROUTES);
I'm also using angular-cli@beta16, but over ubuntu 16. Maybe you should try a clean project and test it.
Hi all, I have the same problem. I have all the routes "inlined" in a DashboardModule file that I wish to lazyload... When I removed the import in my AppModule, my app crashed with a EXCEPTION: Uncaught (in promise): Error: Cannot match any routes: 'dashboard'
error message... If I add DashboardModule to my @NgModule's imports, it works as expected.
Also, ng serve --prod
creates 2 sets of main.*.bundle.js
and styles.*.bundle.js
as expected when DashboardModule is not imported
My AppModule:
@NgModule({
imports: [
BrowserModule,
HttpModule,
CommonModule,
FormsModule,
RouterModule.forRoot([
{ path: '', component: LandingpageModule},
{ path: 'dashboard', loadChildren: `app/dashboard/dashboard.module#DashboardModule`}
]),
LandingpageModule,
],
bootstrap: [AppComponent],
providers: [
LoggedInGuard,
authConfigProvider,
JwtHelper,
AuthHttp,
AuthService
],
declarations: [AppComponent],
})
export class AppModule {}
And my DashboardModule:
@NgModule({
imports: [
FormsModule,
RouterModule.forChild([{
path: 'dashboard',
component: DashboardComponent,
children: [
{ path: '', component: HomeComponent,canActivate: [LoggedInGuard]},
{ path: 'profile', component: ProfileComponent, canActivate: [LoggedInGuard] },
{ path: 'billing', component: BillingComponent, canActivate: [LoggedInGuard, AdminGuard] },
{ path: 'administration', component: AdministrationComponent, canActivate: [LoggedInGuard, AdminGuard] },
],
canActivate: [LoggedInGuard]
}]),
CommonModule,
],
providers: [
AdminGuard
],
declarations: [
HomeComponent, StatusPanelComponent,DashboardComponent,
ProfileComponent,AdministrationComponent,BillingComponent
]
})
export class DashboardModule {}
@Richard87 you should set root path in DashboardModule as path: ''
. So it will be
RouterModule.forChild([{
path: '',
component: DashboardComponent,
children: [
@neilhem Thanks! The routing works, but I still don't get lazy loading? (There are no reference to DashboardModule in AppModule except for the loadChildren string)...
Also, it doesn't seem like ng serve --prod
produces 2 bundle js files (I might have been wrong earlier, it looks like 1 of them where gzipped...)
Asset Size Chunks Chunk Names
assets/fonts/FontAwesome.otf 125 kB [emitted]
main.ef31a7b0feb1135ed298.bundle.js 1.2 MB 0, 2 [emitted] main
inline.js 1.39 kB 2 [emitted] inline
styles.667c85c265538fc61bbe.bundle.js.gz 26.6 kB [emitted]
main.ef31a7b0feb1135ed298.bundle.js.gz 285 kB [emitted]
index.html 542 bytes [emitted]
assets/.npmignore 0 bytes [emitted]
assets/fonts/fontawesome-webfont.eot 76.5 kB [emitted]
assets/fonts/fontawesome-webfont.svg 392 kB [emitted]
assets/fonts/fontawesome-webfont.ttf 153 kB [emitted]
assets/fonts/fontawesome-webfont.woff 90.4 kB [emitted]
assets/fonts/fontawesome-webfont.woff2 71.9 kB [emitted]
styles.667c85c265538fc61bbe.bundle.js 162 kB 1, 2 [emitted] styles
Any tips on how to troubleshoot?
You should not import files from other lazy modules in your lazy module
What do you mean? Like my AuthService or AuthHttp?
Also, I only have 1 lazy module, DashboardModule. my other 2 modules, AppModule and LandingpageModule doesnt import anything from DashboardModule or its components...
Double check that global & local versions of angular-cli is the latest.
Thanks, should work:
C:\Users\richa\Prosjekt\phono-frontend>ng --version
angular-cli: 1.0.0-beta.16
node: 6.3.0
os: win32 x64
C:\Users\richa\Prosjekt\phono-frontend>node_modules\.bin\ng --version
angular-cli: 1.0.0-beta.16
node: 6.3.0
os: win32 x64
C:\Users\richa\Prosjekt\phono-frontend>cd ..
C:\Users\richa\Prosjekt>ng --version
angular-cli: 1.0.0-beta.16
node: 6.3.0
os: win32 x64
Hmm, I think there are some strange "residual" files after I run ng serve --prod
I was trying to clean up the project, so I deleted all *.ngfactory.ts
-files, aaand angular stopped finding my dashboard module again (didn't complain about route or anything, just couldn't find the module).
Then I added DashboardModule to AppModules imports, and ofcourse it works again.. BUT when I removed DashboardModule's import (both inside @NgModule and javascript import {} from ...
it still works.
So my conclusion is that I am importing DashboardModule in some old files, and that's why it doesnt work, but when I clean out the build files, why doesn't angular find my DashboardModule?
I can't reproduce the error where angular can't find dashboard module, so I have literary no idea whats going on..
Same issue with 1.0.0-beta.16
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { DocumentsPage } from "./documents";
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([{ path: '', component: DocumentsPage}])
],
declarations: [ DocumentsPage ],
})
export class DocumentsModule { }
and in my RouterModule.forRoot([...]):
{ path: 'documents', loadChildren: '/documents.module#DocumentsModule' }
When I replace loadChildren with component: fooCmp
, DocumentsPage is not included in the main.bundle.js. Otherwise, using loadChildren includes the component in main.bundle.js
figured out the culprit; import * as moment from 'moment'
anywhere in the eagerly-loaded module will prevent lazy loading, and instead loadChildren modules will be included in the main bundle. I suspect importing d3 and other libraries will have the same issue.
The work around is to define the library in angular-cli.json' scripts definitions, and add a declare var moment: any
in the typescript code, instead of an import.
However, workaround fails if other imported libraries has that import * as moment
in its source code. For example, ng2-bootstrap's datepicker module : /
Workaround to that workaround is to fork valor's ng2-bootstrap datepicker...
So in other words, if there is a import * from xxx
anywhere we are f****?
What about the 100+ that exist in my node_modules folder?
EDIT Is it solvable (by angular-cli or webpack), or must all modules specify their imports?
I did not yet investigate, but I made a repo that can reproduce this issue: https://github.com/aaronleeucla/angular-cli-lazy-load-bug-repro/blob/master/src/app/app-routing.module.ts
Running ng serve
on this project, you can see that when either DatepickerModule is imported into NgModule or when moment() is used in the eagerly loaded MainPage component, lazy loading fails silently.
Great work figuring out the cause @aaronleeucla! This definitely should not happen and is a bug.
Can confirm, @aaronleeucla 's workaround makes angular-cli create multiple bundles again :+1:
For nested routing setup (Gist here) like this:
export const eagerAppRoutes: Routes = [
{ path: '', children: [
{ path: 'home' },
{ path: '',
children: [
{ path: '', /* loadChildren: './viewer/viewer.module#ViewerModule', */
children: [
{ path: '_',
children: [
{ path: '', /* loadChildren: '../editor/editor.module#EditorModule', */
children: [
{ path: '', component: EditorComponent },
{ path: ':model', component: EditorComponent },],},]},]},]},
{ path: '**', redirectTo: 'home' },
]}];
only one chunk will be created (with ViewerModule
), but EditorModule
route will be ignored. There will be runtime errors cannot find module './editor/editor.module#EditorModule'
.
If I add this to the app-routing.module.ts
, (a route _
will never be matched here) both chunks will be created and routing will work:
{ path: '', canLoad: [AuthGuard], loadChildren: './viewer/viewer.module#ViewerModule' },
{ path: '_', canLoad: [AuthGuard], loadChildren: './editor/editor.module#EditorModule' }
Also note that loadChildren url in Viewer module should be ../editor/etc
since this module is in sibling folder to the viewer module, but it does work with ./editor/etc
(just one dot) if I include link in both places.
I'm using cli beta.17; angular 2.1.0; router 3.1.0
To recap: For nested lazy loaded routes (Gist here) only one chunk is created if I don't add both route definitions to the root; if I do, both chunks are generated and routing works as expected.
Thanks a lot @aaronleeucla (may you get struck with good fortune today). I couldn't figure out why Webpack was no longer generating separate chunk.js files for my lazy routes. Your solution worked for me. Moving import * as moment ...
components into lazy loaded modules/routes (thus removing them from the eager ones) fixed this.
Any progress with this issue @filipesilva? It has label "priority: 1 (urgent)" almost one month. It is blocking me to update my project to newest angular-cli version.
I have the same problem with angular-cli beta18.
With beta16, with an application using momentjs (and import * as moment from ''), I did not have any issues.
@aaronleeucla Which version of angular-cli are you using ?
Manu
For what's worth, I've the same problem too using angular-cli beta18
Is this related only to importing moment.js ? Because I am using angular-cli 18 and everything seems to work fine regarding lazy loading
@Mihai-B Sorry, yes it is related to importing moment.js.
This is really breaking everything.. I'm facing the exact same issue. A Fix for this is much appreciated.
I even tried with angular-cli: 1.0.0-beta.19-3
.. but the issue still exists.
Looks like this issue was introduced in beta.18
@a5hik
Looks like this issue was introduced in beta.18
I also tried with beta.17 and even 16 and have the same issue =)
Help plz, trying to lazy load one module getting same issue
Error: Cannot match any routes. URL Segment: 'admin'
i am using:
angular-cli: 1.0.0-beta.19-3 node: 6.7.0 os: win32 x64
"ng2-bootstrap": "^1.1.16",
package.json
"dependencies": { "@angular/common": "2.1.2", "@angular/compiler": "2.1.2", "@angular/core": "2.1.2", "@angular/forms": "2.1.2", "@angular/http": "2.1.2", "@angular/platform-browser": "2.1.2", "@angular/platform-browser-dynamic": "2.1.2", "@angular/router": "~3.1.0", "bootstrap": "^3.3.7", "core-js": "^2.4.1", "ng2-bootstrap": "^1.1.16", "ng2-sidebar": "^1.6.2", "rxjs": "5.0.0-beta.12", "ts-helpers": "^1.1.1", "zone.js": "^0.6.23" }, "devDependencies": { "@types/jasmine": "^2.2.30", "@types/node": "^6.0.42", "angular-cli": "1.0.0-beta.19-3", "codelyzer": "1.0.0-beta.1", "jasmine-core": "2.4.1", "jasmine-spec-reporter": "2.5.0", "karma": "1.2.0", "karma-chrome-launcher": "^2.0.0", "karma-cli": "^1.0.1", "karma-jasmine": "^1.0.2", "karma-remap-istanbul": "^0.2.1", "protractor": "4.0.9", "ts-node": "1.2.1", "tslint": "3.13.0", "typescript": "~2.0.3", "webdriver-manager": "10.2.5" }
You will have to wait for beta 20, lazy loading isn't really working yet.
@achimha What do you mean? Of course it's working, even with 3rd party libs using the workaround mentioned above.
@VinayLeaf post your question with code on stackoverflow and I can help you there
The workaround means modifying the library and if the library depends on a library which depends on a library etc. the workaround isn't really workable.
However, beta 20 is probably out very soon and then things should be much better.
agree with @ciesielskico, it's really working with workaround. Tried with latest cli
Can anyone tell me that how to use that workaround???
On 11-Nov-2016 3:45 pm, "Serhii Sol" notifications@github.com wrote:
agree with @ciesielskico https://github.com/ciesielskico, it's really working with workaround. Tried with latest cli
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/angular/angular-cli/issues/2496#issuecomment-259926017, or mute the thread https://github.com/notifications/unsubscribe-auth/AQo1nUyqcETorUxa08j3-wesrSvDsn4fks5q9EBWgaJpZM4KNcjN .
@VinayLeaf All you need to do is to avoid wildcard imports e.g.:
import * as moment from 'moment'
instead you need to include import into angular-cli.json e.g.:
"scripts": [
"../node_modules/moment/moment.js"
]
and then add typing for moment e.g.:
declare var moment: any;
And that's pretty it. I hope that will help you :)
PS. also you can try to import it as polyfill, but declaration of variable still should be added somewhere in types
Need to declare var instead of import * as momment from 'moment'?? Every where??
On 11-Nov-2016 3:51 pm, "Serhii Sol" notifications@github.com wrote:
@VinayLeaf https://github.com/VinayLeaf All you need to do is to avoid wildcard imports e.g.:
import * as moment from 'moment'
instead you need to include import into angular-cli.json e.g.:
"scripts": ["../node_modules/moment/moment.js" ]
and then add typing for moment e.g.:
declare var moment: any;
And that's pretty it. I hope that will help you :)
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/angular/angular-cli/issues/2496#issuecomment-259926983, or mute the thread https://github.com/notifications/unsubscribe-auth/AQo1nYYjRRUqXfsSGuhD3q8jyjpjcwmTks5q9EGfgaJpZM4KNcjN .
@VinayLeaf only once in typings somewhere (where's your types) and then use moment as global.
@serhiisol i found 2 occurrences of import * as moment from 'moment'
in following location
node_modules\awesome-typescript-loader\issues\product-designer\src\components\products node_modules\awesome-typescript-loader\issues\product-designer\src\constants
than i have replaced import * as moment from 'moment'
to import * from 'moment'
i have included following code in angular-cli.json
"scripts": [ "../node_modules/moment/moment.js" ]
than i have declared declare var moment: any;
in typings.d.ts
still i am getting following error
error_handler.js:47 EXCEPTION: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'admin'
am i doing something wrong?
if you want to look at my file how they looks: than got this link http://stackoverflow.com/questions/40531095/lazy-loading-not-working-with-angular-cli-webpack
@serhiisol i found that if i am not using ng2-bootstrap module than my lazy loading is working fine. and i also looked for import * as moment from 'moment'
but i foundvar moment = require('moment');
i also tried to user workaround but still its not working.
@serhiisol i found solution i was doing mistake in my code, its my bad.
look at here: http://stackoverflow.com/questions/40531095/lazy-loading-not-working-with-angular-cli-webpack
Anybody get the workaround working with AOT? (I'm using 1.0.0-beta.20-4) Without AOT it just shows warning "Cannot find namespace 'moment'." for each component file that I use moment in but app still runs, With AOT I get
ERROR in ./src/app/app.module.ngfactory.ts
Module build failed: Error: <my component that uses moment>): Cannot find namespace 'moment'.)
.....
And app doesnt start.
I've just read this thread up to the first comment mentioning momentjs. I remembered that I had this similar issue once, declaring moment in angular-cli.json scripts fixed it.
I don't know if this solution has been provided, as I said, I haven't read the entire thing. If not, you could try that.
angular-cli: 1.0.0-beta.20-4 node: 7.0.0 os: darwin x64
The lazy loading still not working.. with aot I was able to generate the map files for all the modules. But only getting one main chunk created.. no module chunks. So everything gets loaded when the app loads with one big main chunk.
Adding simply the below Fixed the issue..
"../node_modules/moment/moment.js"
in angular-cli.json
But this should be a workaround.. and not the actual Fix.
Lazy loading is still not working for me...
angular-cli: 1.0.0-beta.21
node: 6.9.1
os: win32 x64
PSA: My previously suggested workaround (declare var moment
instead of importing moment) should also be applied to code in lazy modules as well. Per my issue reference above, I found that if one were to use import * as moment from 'momemt
in a lazy module, that module will then duplicate the code from all other lazy chunks. bad!
However, even if you don't import moment, if one of the dependency in a lazy module uses such import, such as ng2-bootstrap's datepicker, the module will still duplicate. sad!
@Gillespie59 I've been running beta.22 / angular 2.2.3 and this bug still appears.
Correction, when I say it appears, I mean in the form of lazy chunks code being duplicated, per #3410 . I have not reproducing this bug by having import moment the eager module.
Just upgraded to beta.22 from beta.18. Lazy loading is still not working but instead of not generating the chunks now my application does not run at all.
As my project comes from several angualr-cli upgrades I created a brand new project to be sure the error is not related to my code. When I try to navigate to a lazy route I get this error:
error_handler.js:47EXCEPTION: Uncaught (in promise): Error: Cannot find module 'app/my-route/my-route.module'.
Error: Cannot find module 'app/my-route/my-route.module'.
at webpackEmptyContext (http://localhost:4200/main.bundle.js:41:8)
at SystemJsNgModuleLoader.loadAndCompile (http://localhost:4200/vendor.bundle.js:51252:40)
at SystemJsNgModuleLoader.load (http://localhost:4200/vendor.bundle.js:51244:60)
at RouterConfigLoader.loadModuleFactory (http://localhost:4200/vendor.bundle.js:66070:128)
at RouterConfigLoader.load (http://localhost:4200/vendor.bundle.js:66061:81)
at MergeMapSubscriber.project (http://localhost:4200/vendor.bundle.js:68848:111)
at MergeMapSubscriber._tryNext (http://localhost:4200/vendor.bundle.js:66195:27)
at MergeMapSubscriber._next (http://localhost:4200/vendor.bundle.js:66185:18)
at MergeMapSubscriber.Subscriber.next (http://localhost:4200/vendor.bundle.js:41971:18)
at ScalarObservable._subscribe (http://localhost:4200/vendor.bundle.js:68111:24)
I also struggled with loadChildren a whole workday and discovered in the source code, that using backticks ` will not work, because it's not ts.SyntaxKind.StringLiteral
.
You have to use double- \" or singlequotes \' for enclosing the loadChildren path.
Maybe some of you stepped into the same pitfall than me.
@sclausen I am already using single quotes. I've tested with double quotes and I get the same error...
angular-cli: 1.0.0-beta.16 node: 5.7.1 os: darwin x64
Repro steps.
I have this route in my app.routing.ts: