Angular-cli: AOT : Chunk files missing and big size files for lazy loaded files

Created on 27 Dec 2016  路  22Comments  路  Source: angular/angular-cli

I am concerned about the size and type of bundles generated by cli .
Previously there are 2-3 bundles which will be loaded on demand only . But in current version it shows the main bundle size is increased and there are no bundles for the lazy loaded bundles. Since am using same codebase i get different bundle size.

This is my app-routing

import { NgModule } from '@angular/core';
import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
import { LoginComponent } from './auth/login.component';
import { AuthGuard } from './auth/auth.guard';
const routes: Routes = [
    {
        path:'',
        redirectTo: '/login',
        pathMatch: 'full'
    },
    {
        path:'login',
        //component: LoginComponent
        loadChildren: './auth/auth.module#AuthModule',
    },
    {
        path: 'tickets',
        loadChildren: './tickets/tickets.module#TicketsModule',
        canActivate:[AuthGuard],        
    },
    {
        path: 'clients',
        loadChildren: './clients/clients.module#ClientsModule',
        canActivate: [AuthGuard],   
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routes, { useHash: true, preloadingStrategy: PreloadAllModules })],
    exports: [RouterModule],
    providers: []
})
export class MyRoutingModule { }

Here are my test results
Angular -cli : 1.0.0-beta.21
aot_cli21

Angular- cli:1.0.0-beta.24
Command : ng build --prod --aot
aot-cli24

Angular- cli:1.0.0-beta.24
Command : ng build --prod
withoutaot-cli24

Angular- cli:1.0.0-beta.24
Command : ng build
build-cli24

You can see the difference. While build with aot in 21 makes a big difference in size.
While in 24 , even using --aot doesn't change the size of the bundle and also there is no separate chunk for modules.

OS?

Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?)
Ubuntu 14.04

Versions.

Please run ng --version. If there's nothing outputted, please run in a Terminal: node --version and paste the result here:
angular-cli: 1.0.0-beta.24
node: 6.9.1
os: linux x64
@angular/common: 2.4.1
@angular/compiler: 2.4.1
@angular/core: 2.4.1
@angular/forms: 2.4.1
@angular/http: 2.4.1
@angular/material: 2.0.0-beta.1
@angular/platform-browser: 2.4.1
@angular/platform-browser-dynamic: 2.4.1
@angular/router: 3.4.1
@angular/compiler-cli: 2.4.1

Repro steps.

Was this an app that wasn't created using the CLI? What change did you do on your code? etc.

The log given by the failure.

Normally this include a stack trace and some more information.

Mention any other details that might be useful.


Thanks! We'll be in touch soon.

repro steps 1 (urgent)

Most helpful comment

I'm seeing a possibly related issue in the following setup: I have two lazy-loaded modules A and B which both make use of chart.js in a separate NgModule (not imported from main/root bundle, only from A and B).

From looking at the generated bundles, both chunks contain a full copy of chart.js....

@harilalinapp is that issue similar to what you are seeing?

@hansl is that the expected behavior of webpack in this case? I was expecting it would generate three chunks (for A, B and the chart NgModule) and lazy-loading the third.

All 22 comments

I have the same problem

I think there is a couple things going on here. I ran ng build --prod --aot and ended up with a 3.16mb main and a 3.01mb vendor. Running ng build --aot resulted in a .01kb increase in my main. Maybe shaking is disabled?

angular-cli: 1.0.0-beta.24
node: 6.3.1
os: darwin x64
@angular/common: 2.4.1
@angular/compiler: 2.4.1
@angular/core: 2.4.1
@angular/forms: 2.4.1
@angular/http: 2.4.1
@angular/platform-browser: 2.4.1
@angular/platform-browser-dynamic: 2.4.1
@angular/router: 3.4.1
@angular/compiler-cli: 2.4.1

image

@TheLarkInn

I think that problem is not in disabled shaking because viewing vendor.bundle with source-map-explorer revealed that angular compiler is still in bundle

@jujyfruits part of it is the disabled shaking. import { ActivatedRoute } from '@angular/router/src/router_state'; when I change ActivtedRoute to not use the barrel I shave off .2kb.

I'd appreciate a small repro where this happens so we could look at debugging it. In our current tests we can't see this happening.

Hi
I will share the code . Since it's in prod i can't share all so I need to remove some thing and will share the same.
The project is created in beta 16 and updates timely since 20. After updating to 24 the chunk files were missing .

Is it okay , if i share my essential codes? I can't share the code.
It's my package.json
{ "name": "", "version": "0.0.0", "license": "MIT", "angular-cli": {}, "scripts": { "ng": "ng", "start": "ng serve", "lint": "tslint \"src/**/*.ts\"", "test": "ng test", "pree2e": "webdriver-manager update --standalone false --gecko false", "e2e": "protractor" }, "private": true, "dependencies": { "@angular/common": "2.4.1", "@angular/compiler": "2.4.1", "@angular/core": "2.4.1", "@angular/forms": "2.4.1", "@angular/http": "2.4.1", "@angular/material": "^2.0.0-beta.1", "@angular/platform-browser": "2.4.1", "@angular/platform-browser-dynamic": "2.4.1", "@angular/router": "3.4.1", "@types/hammerjs": "2.0.33", "@types/jquery": "2.0.34", "@types/lodash": "4.14.36", "angular2-cookie": "1.2.6", "bootstrap": "3.3.7", "core-js": "2.4.1", "hammerjs": "2.0.8", "jquery": "3.1.1", "lodash": "4.16.3", "ng2-bootstrap": "1.1.16-9", "primeng": "1.1.2", "rxjs": "^5.0.1", "ts-helpers": "^1.1.1", "zone.js": "^0.7.2" }, "devDependencies": { "@angular/compiler-cli": "2.4.1", "@types/jasmine": "2.5.38", "@types/node": "^6.0.42", "angular-cli": "1.0.0-beta.24", "codelyzer": "~2.0.0-beta.1", "jasmine-core": "2.5.2", "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.13", "ts-node": "1.2.1", "tslint": "^4.0.2", "typescript": "~2.0.3" } }
My angular-cli.json
{ "project": { "version": "1.0.0-beta.24", "name": "" }, "apps": [ { "root": "src", "outDir": "dist", "assets": [ "assets", "assets/favicon.ico" ], "index": "index.html", "main": "main.ts", "test": "test.ts", "tsconfig": "tsconfig.json", "prefix": "ks", "mobile": false, "styles": [ "../node_modules/@angular/material/core/theming/prebuilt/indigo-pink.css", "../node_modules/bootstrap/dist/css/bootstrap.min.css", "../node_modules/primeng/resources/themes/omega/theme.css", "../node_modules/primeng/resources/primeng.min.css", "assets/css/font-awesome.min.css", "assets/css/style.css", "assets/css/common.css" ], "scripts": [ "../node_modules/jquery/dist/jquery.min.js", "../node_modules/bootstrap/dist/js/bootstrap.js" ], "environments": { "source": "environments/environment.ts", "dev": "environments/environment.ts", "prod": "environments/environment.prod.ts" } } ], "addons": [], "packages": [], "e2e": { "protractor": { "config": "./protractor.conf.js" } }, "test": { "karma": { "config": "./karma.conf.js" } }, "defaults": { "styleExt": "css", "prefixInterfaces": false, "inline": { "style": false, "template": false }, "spec": { "class": false, "component": true, "directive": true, "module": false, "pipe": true, "service": true } } }
Main.ts
`import './polyfills.ts';

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { AppModule } from './app/app.module';

if (environment.production) {
enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);
app.module.ts import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { MaterialModule } from '@angular/material';
import 'hammerjs';
import { AppComponent } from './app.component';
import { ConfigService } from './shared/config.service';
import { AuthService } from './auth/auth.service';
import { AuthGuard } from './auth/auth.guard';
import { KarisoftRoutingModule } from './app-routing.module';
import { SharedModule } from './shared/shared.module';
import { CoreModule } from './core.module';
import { SharedService } from './shared/shared.service';
import { OdataService } from './odata/odata.service';
import { ClientService } from './clients/clients.service';

import { TimepickerModule,ModalModule,TooltipModule,TabsModule } from 'ng2-bootstrap';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule,
KarisoftRoutingModule,
SharedModule,
CoreModule,
MaterialModule.forRoot(), TimepickerModule.forRoot(),
ModalModule.forRoot(), TooltipModule.forRoot(), TabsModule.forRoot()
],
providers: [ConfigService,
SharedService,
AuthService,
AuthGuard,
OdataService,
ClientService],
bootstrap: [AppComponent]
})
export class AppModule { }
app.routiing import { NgModule } from '@angular/core';
import { Routes, RouterModule, PreloadAllModules } from '@angular/router';
import { LoginComponent } from './auth/login.component';
import { AuthGuard } from './auth/auth.guard';

const routes: Routes = [
{
path:'',
redirectTo: '/login',
pathMatch: 'full'
},
{
path:'login',
loadChildren: './auth/auth.module#AuthModule',
},
{
path: 'tickets',
loadChildren: './tickets/tickets.module#TicketsModule',
canActivate:[AuthGuard],
data: {
preload: true
}
},
{
path: 'clients',
loadChildren: './clients/clients.module#ClientsModule',
canActivate: [AuthGuard],
data: {
preload: true
}
}
];

@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true, preloadingStrategy: PreloadAllModules })],
exports: [RouterModule],
providers: []
})
export class KarisoftRoutingModule { }
tickets.module import { NgModule } from "@angular/core"
import { DatePipe } from '@angular/common';
import { MaterialModule } from '@angular/material';
import {AccordionModule} from 'primeng/components/accordion/accordion';
import {DataTableModule} from 'primeng/components/datatable/datatable';
import {DropdownModule} from 'primeng/components/dropdown/dropdown';
import {CheckboxModule} from 'primeng/components/checkbox/checkbox';
import {OverlayPanelModule} from 'primeng/components/overlaypanel/overlaypanel';
import {InputTextModule} from 'primeng/components/inputtext/inputtext';
import {AutoCompleteModule} from 'primeng/components/autocomplete/autocomplete';
import {DialogModule} from 'primeng/components/dialog/dialog';
import {CalendarModule} from 'primeng/components/calendar/calendar';
import {ModalModule } from 'ng2-bootstrap/modal';
import {TimepickerModule } from 'ng2-bootstrap/timepicker';
import {TabsModule } from 'ng2-bootstrap/tabs';
import { TooltipModule } from 'ng2-bootstrap/tooltip';

import { SharedModule} from 'app/shared/shared.module';
import { CoreModule } from 'app/core.module';
import { TicketRoutesModule } from "./tickets.routes";
import { TicketsComponent } from "./tickets.component";
import { TicketListComponent } from './ticket-list/ticket-list.component';
import { NewTicketComponent } from './new-ticket/new-ticket.component';
import { TlistHeaderComponent } from './ticket-list/tlist-header.component'
import { TicketService } from './ticket.service'
import { TicketTableComponent } from './ticket-list/ticket-table.component';
import { FilterPopComponent } from './ticket-list/filter-pop.component';
import { StartpopComponent } from './components/startpop.component';
import { StoppopComponent } from './components/stoppop.component';
import { PrintpopComponent } from './components/printpop.component';
import { PausepopComponent } from './components/pausepop.component';
import { AppendpopComponent } from './components/appendpop.component';
import { NewTaskComponent } from './components/new-task.component';
import { ContinueTaskComponent } from './components/continue-task.component';
import { UserinitialDirective } from './directives/userinitial.directive';
import { FollowupDirective } from './directives/followup.directive';

@NgModule({
declarations: [
TicketsComponent,
TicketListComponent,
TlistHeaderComponent,
TicketTableComponent,
NewTicketComponent,
FilterPopComponent,
StartpopComponent,
StoppopComponent,
PrintpopComponent,
PrintpopComponent,
PausepopComponent,
NewTaskComponent,
ContinueTaskComponent,
UserinitialDirective,
AppendpopComponent,
FollowupDirective
],

imports: [TicketRoutesModule,
            SharedModule,DropdownModule, 
            DataTableModule,CheckboxModule,
            OverlayPanelModule,InputTextModule,
            AccordionModule,AutoCompleteModule,
            CoreModule,
            MaterialModule,
            DialogModule,CalendarModule,
            ModalModule,TimepickerModule,
            TabsModule, TooltipModule

     ],

providers: [TicketService, DatePipe],
exports: []

})

export class TicketsModule { }`

As mentioned earlier the poject is created on beta.16.

ng -v

angular-cli: 1.0.0-beta.24
node: 6.9.1
os: linux x64
@angular/common: 2.4.1
@angular/compiler: 2.4.1
@angular/core: 2.4.1
@angular/forms: 2.4.1
@angular/http: 2.4.1
@angular/material: 2.0.0-beta.1
@angular/platform-browser: 2.4.1
@angular/platform-browser-dynamic: 2.4.1
@angular/router: 3.4.1
@angular/compiler-cli: 2.4.1

I'm also experiencing missing chunks, this happens when the router tree looks like

 - +subroute1
   - +route
     - +subroute1
 - +subroute2
 - +subroute3

If I put every route at the same level the modules can be found but as soon as it's like the above it doesn't work which is really stupid because it doesn't make sense to have child routes at the same tree level as the parent route..

i have downgraded it to 1.0.0-beta.21 and now i have the chunk files. Though the size were big now we have multiple chunks. Please see the attchment
screenshot from 2017-01-02 21-35-14

@filipesilva could you please look into this.

@harilal Beta.21 doesn't have AOT by default, that's probably why you have the chunk files there.

@chrillewoodz then AOT is not working in the latest version also, right?

Yes, there's another open issue that suggests that AOT is broken with 2 level deep nested routes. They're working on fixing it.

@filipesilva @chrillewoodz which version does support AOT for lazy loading? 19-3 supports AOT?

I have a similar issue on .25.5 using PROD and AOT.

It only ever generates the 4 main bundles although I am using Child Routes and lazy loading. Interestingly, I had the same problem on .21 (ie. I have never seen extra chunk files with lazy loading).

The issue is still there after updating to latest 28-3. Please see below screenshots

ng build --prod
build_prod

ng build --aot --prod
build_aot_prod

Is ther any way to analye the bundles , what takes the major space . If anyone could help me to use that sort of tool it will be helpfull in determining the problem

You can inspect the bundles - see https://angular.io/docs/ts/latest/cookbook/aot-compiler.html "Inspect the Bundle"

Please find the detailed test with bundle analyser
ng --prod
prodonly

0.chunk.js
prodonly_0_chunk

vendor.chunk.js
prod_only_vendor

ng --prod --aot --sm
prod--aot

0.chunk.js
prod-aot-0

vendor.chunk.js
prod-aot-vendor

I think it will help to figure out what went wrong. Anyway it gives extremely different file size for same code.

@hansl Could you please reopen this issue. This issue is still there . And the size has increased lot in v30.

I'm seeing a possibly related issue in the following setup: I have two lazy-loaded modules A and B which both make use of chart.js in a separate NgModule (not imported from main/root bundle, only from A and B).

From looking at the generated bundles, both chunks contain a full copy of chart.js....

@harilalinapp is that issue similar to what you are seeing?

@hansl is that the expected behavior of webpack in this case? I was expecting it would generate three chunks (for A, B and the chart NgModule) and lazy-loading the third.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings