Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating multiple bundles using angular-cli webpack

Tags:

When i build the project using angular-cli, it bundles all project files into one big main bundle.

I have used lazy routing in the application and i can navigate fine once application loads up.

Is there a way in which main bundle is divided into multiple files based upon lazy loaded routes modules?

below is the configuration in angular-cli.json

    {
  "project": {
    "version": "1.0.0-beta.15",
    "name": "maddy-test-project"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": "styles/content",
      "index": "default.htm",
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "",
      "mobile": false,
      "styles": [
        "styles.less"
      ],
      "scripts": [
        "styles/wfa-myriad-pro-typekit.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": "less",
    "prefixInterfaces": false
  }
}

below is package.json

{
  "name": "maddy-test-project",
  "version": "0.0.1",
  "license": "MIT",
  "angular-cli": {},
  "scripts": {
    "start": "ng serve",
    "lint": "tslint \"src/**/*.ts\"",
    "test": "ng test",
    "pree2e": "webdriver-manager update",
    "e2e": "protractor"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "2.0.0",
    "@angular/compiler": "2.0.0",
    "@angular/core": "2.0.0",
    "@angular/forms": "2.0.0",
    "@angular/http": "2.0.0",
    "@angular/platform-browser": "2.0.0",
    "@angular/platform-browser-dynamic": "2.0.0",
    "@angular/router": "3.0.0",
    "d3": "^4.2.3",
    "jquery": "^3.1.0",
    "lodash": "^4.15.0",
    "moment": "^2.15.0",
    "core-js": "^2.4.1",
    "rxjs": "5.0.0-beta.12",
    "toastr": "^2.1.2",
    "ts-helpers": "^1.1.1",
    "zone.js": "^0.6.23",  
    "bootstrap-daterangepicker": "^2.1.24"
  },
  "devDependencies": {
    "@types/d3": "^3.5.35",
    "@types/google-maps": "^3.1.27",
    "@types/jasmine": "^2.2.30",
    "@types/jquery": "^1.10.31",
    "@types/lodash": "^4.14.34",
    "@types/toastr": "^2.1.29",
    "angular-cli": "1.0.0-beta.15",
    "codelyzer": "~0.0.26",
    "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.5",
    "ts-node": "1.2.1",
    "tslint": "3.13.0",
    "typescript": "2.0.2"
  }
}

Thanks in advance!!

like image 826
Madhu Ranjan Avatar asked Sep 21 '16 14:09

Madhu Ranjan


People also ask

Does Angular CLI use webpack?

Angular-CLI uses webpack under the hood and only configures it. In this article I will show step-by-step how it's done using webpack.

How bundling happens in Angular?

To understand how bundling works in an Angular app, you don't need to look further than the angular. json file. The angular. json file that is generated for your Angular app is the configuration file that is used by the underlying build system contained within the Angular CLI.

Does ng build use webpack?

The application builder uses the webpack build tool, with default configuration options specified in the workspace configuration file ( angular. json ) or with a named alternative configuration.


2 Answers

It is the role of NgModule and RouterModule.forChild(). Here is a very good article for starting big Angular 2 modular aplications developpement : http://blog.angular-university.io/angular2-ngmodule/

The first thing that we need to do is to remove every mention of the Home component or the HomeModule from the App component and the main routing configuration:

We can see here that the App component no longer imports HomeModule, instead the routing config uses loadChildren to say that if /home or any other url starting with it gets hit, then the file home.module should be loaded via an Ajax call.

Shortly, to move some logic and components in a lazy module, you can run this command :

ng g module child --routing

Then angular-cli will generate a NgModule (app/child/child.module.ts) and a child router configuration (app/child/child-routing.module.ts).

The route for lazy loading this child router will be :

 { path: 'child', loadChildren: 'app/child/child.module#ChildModule' }

And finally move what you want in your ChildModule with one constraint : other module (as AppModule) will not be able to use any ChildModule dependency (like a service, for example). If you need it, a good practice is to create a shared module.

like image 58
Karbos 538 Avatar answered Oct 01 '22 18:10

Karbos 538


If your splitting the areas that you want to be lazy loaded into separate modules, you should be able to produce multiple bundles. Take a look at this plnkr on routing and navigation taken directly from the angular.io website. If you configure your routes this way you should be able to produce a build when running ng serve similar to:
enter image description here Notice the chunk files. In my project, these chunk files get loaded asynchronously when navigating to the 'crisis' and 'heroes' routes.

export const routes: Routes = [
  { path: '', redirectTo: 'contact', pathMatch: 'full'},
  { path: 'crisis', loadChildren: 'app/crisis/crisis.module#CrisisModule' },
  { path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule' }
];
like image 33
Mike Lunn Avatar answered Oct 01 '22 19:10

Mike Lunn