Use the Angular CLI For Faster Angular v2+ Projects

Chris Sevilleja

This article has been updated for Angular v4 and Angular CLI v1.2.3

If you've ever gone through the Angular 2 Quickstart or our Angular v4+ Getting Started Course over the past year, you'll know that a big part of getting started with Angular 2 is the setup.

It included things like:

  • Creating our app files
  • Configuring TypeScript and Typings
  • Adding script tags for
    • Angular 2
    • Rx.js
    • System.js
  • Configuring System.js
  • Creating our Angular 2 app component
  • Bootstrapping our Angular 2 application

Talk about a lot! Thankfully, at ng-conf 2016, the Angular team announced a tool that will make creating and scaffolding Angular 2 applications incredibly easy.

The Angular CLI cli.angular.io

Angular CLI Homepage

The Angular CLI effectively takes all those configuration and setup steps shown above and condenses it down into one quick line:

ng new scotchy-scotch

There are many things that the CLI can do so let's get it installed and walk through some features.

Installing the Angular CLI

To install the CLI, we'll use Node and npm.

npm install -g @angular/cli

That's it! Now we can start using the CLI to build out our applications.

Starting a New Application

To start a new application, just run the command we saw earlier:

ng new scotchy-scotch

Angular CLI ng new

So what exactly does this do for us? Let's take a look at the newly generated folders and files:

// end-to-end-tests
|- e2e/
  |----- app.e2e-spec.ts
  |----- app.po.ts
  |----- tsconfig.e2e.json

// npm dependencies
|- node_modules/

// public facing app. built things go here. this wont show until we run a build
|- dist/

// where most of the work will be done
|- src/
  |----- app/
      |----- app.component.css|html|spec.ts|ts
      |----- app.module.ts
  |----- assets/
  |----- environments/
      |----- environment.prod.ts|ts
  |----- favicon.ico
  |----- index.html
  |----- main.ts
  |----- polyfills.ts
  |----- styles.css
  |----- test.ts
  |----- tsconfig.app.json
  |----- tsconfig.spec.json
  |----- typings.d.ts

// overall configuration
|- .angular-cli.json  // the main configuration file
|- .editorconfig      // editorconfig which is used in some VS Code setups
|- .gitignore
|- karma.conf.js
|- package.json
|- protractor.conf.js
|- README.md
|- tsconfig.json
|- tslint.json

It's important to take note of this directory structure and where the files are located because the application that the Angular CLI generates follows the recommended app structure and style guide.

The majority of our application is under src/app. This is where we will be working and everything that gets compiled and is available to our final application will be built to the public folder.

Learn from this stucture and style guide and incorporate these things into your own development. The Angular CLI will not only create the files and folders, it will also install any npm dependencies required.

Here is the default package.json that gets created:

{
  "name": "scotchy-scotch",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.0.0",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",
    "core-js": "^2.4.1",
    "rxjs": "^5.1.0",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.2.1",
    "@angular/compiler-cli": "^4.0.0",
    "@angular/language-service": "^4.0.0",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.0.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.0.4",
    "tslint": "~5.3.2",
    "typescript": "~2.3.3"
  }
}

All those dependencies are added and included in our src/index.html file. All of the setup that was in the Angular quickstart are now taken care of for us.

Notice that there's packages for testing with Karma and Protractor and it's great that the CLI handles the beginning setup for testing for us. (We all know adding in testing isn't the first thing on our list when starting new projects).

Check out the src/index.html file and you'll see the beginning of our application with <app-root></app-root>. Our entire Angular app will get injected here.

System.js vs webpack

In previous CLI versions, we would also find the script tags for our dependencies here. Since the CLI is now using webpack, all of the following will be injected for us when serving (developing) or building (production) our application.

<script src="vendor/es6-shim/es6-shim.js"></script>
<script src="vendor/reflect-metadata/Reflect.js"></script>
<script src="vendor/systemjs/dist/system.src.js"></script>
<script src="vendor/zone.js/dist/zone.js"></script>

ng new options

Creating a new application has a few different options we can use. There are many options that can be seen by typing ng help. I'll show off a few of the important ones here:

  • --directory: Specify the directory you want to create this project in
  • --style: (Default: css) The style file default extension. Possible values: css, scss, less, sass, styl(stylus). You can later change the value in ".angular-cli.json" (defaults.styleExt).
  • --prefix (Default: app) The prefix to use for all component selectors. You can later change the value in ".angular-cli.json" (apps[0].prefix)
  • --routing (Default: false) Generate a routing module.

Initialize a New Application in an Existing Folder

Let's say you already have a folder that you've started working in. The ng init command is here so that you can use the current folder you're already working in.

In the folder you are working in, run:

ng init scotchy-scotch

Serving Our Application

Another really cool thing that our CLI allows us to do is to serve our application in the browser. Previously, we would have to create a server using lite-server or create our own Node (or other) server.

The Angular CLI let's us do this with one simple command:

ng serve

Just like that, the Angular CLI will build a server for us with webpack and we can view it in browser at http://localhost:4200

Angular CLI ng serve

Angular CLI Serve Features

What features are given to us with our new server?

  • Built with webpack: Reloads on saves
  • Automatically routed for us
  • Found in the browser at http://localhost:4200
  • Simplicity and ease-of-mind
  • Shows sizes of bundles needed for our app

Generate Parts of Your Application

This is where things get interesting. So far we've just created and instantiated a new project. The ng generate command can do so much for us:

  • Create a new component
  • Create a new directive
  • Create a new route
  • Create a new pipe
  • Create a new service

That's a ton of functionality and helps speed up development. First let's talk about the options that we can use for all of the above.

ng generate options

  • --flat: Don't create the code in it's own directory. Just add all files to the current directory.
  • --route=<route>: Specify the parent route. Only used for generating components and routes.
  • --skip-router-generation: Don't create the route config. Only used for generating routes.
  • --default: The generated route should be a default route.
  • --lazy: Specify if route is lazy. default true

Now we can run through each and see exactly what gets created and how the Angular CLI makes life easier.

Generating a New Component

Components are the foundation of Angular development. Let's generate a new component:

ng generate component hello

# also can be simplified to
ng g component hello

Angular CLI ng generate component


Note: It's important to name your component simply. If a component is created with the name hello, these are the corresponding naming schemes:

  • Folder: hello
  • Files: `hello.component.[css,html,spec.ts,ts]
  • Class: HelloComponent

If you use ng generate component HelloComponent, then your component class will be an undesirable HelloComponentComponent.


Here are the files that get created:

|- src/
  |----- app/
    |----- hello/
      |----- hello.component.css|html|spec.ts|ts

Our new component is relegated to its own folder within the src/app folder. We have all the parts (including tests) that we need for our new component.

Generating a New Module with Routing

In addition to generating components, we can generate modules. Modules are a way we can encapsulate similar functionality into a section of our app.

By separating parts out into their own section, we can treat that module as its own compartment of our app with routing. This will become child routing for our app and then we can even lazy load it!

To generate a module, we can use ng generate module. To add routing to it, we can add the --routing flag.

ng generate module about --routing

Angular CLI ng generate module with routing

We now have a brand new AboutModule that we can include in our main AppModule.

// about.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { AboutRoutingModule } from './about-routing.module';

@NgModule({
  imports: [
    CommonModule,
    AboutRoutingModule
  ],
  declarations: []
})
export class AboutModule { }

We also have the routing for this module:

// src/app/about/about-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class AboutRoutingModule { }

Creating a Component in a Module

So far we've only created a module. Let's say we wanted to build out components within this module. This AboutModule could have a UserComponent to display owner profiles for Scotch.

Let's generate the component with a little trick. We can generate a component to be part of a module.

ng g component about/user

Angular CLI generate child component

We now have our new UserComponent and it lives inside the about folder. We can now use it and route to it using the provided files.

Generating Other Things

The generate command comes with many other things we can generate:

Scaffold Usage
Component ng g component my-new-component
Directive ng g directive my-new-directive
Pipe ng g pipe my-new-pipe
Service ng g service my-new-service
Class ng g class my-new-class
Guard ng g guard my-new-guard
Interface ng g interface my-new-interface
Enum ng g enum my-new-enum
Module ng g module my-module

Building Our App

When we want to prepare our Angular app for deployment, we only need to run one command.

ng build

Angular CLI ng build

The build will take all of our files and bundle them into five main files. It will also generate everything into a dist folder. Go ahead and take a look in there and you'll see your deployment ready files. You'll even notice the index.html file that has all those scripts already injected for you.

Open that index.html file in browser and your Angular app works!

Building for Production

We can also build for production to get some more efficiently sized bundles. Tree shaking goodness and more!

ng build --prod

Building with Ahead-of-Time Compilation

We can also build with AOT to make sure our Angular app is compiled during build-time instead of in browser at run-time. This can help reduce the size of our app by more than half!

ng build --prod --aot

Once you do that, notice the difference in bundle sizes from the previous non-aot build.

Angular CLI ng build --prod --aot

1.89MB vs 849kb! AOT FTW

More Commands

As the CLI get's more hashed out and more information, we'll be filling out this section with more commands and what they do. Some of these commands were a little buggy when we first tested out the CLI since it's in v1.0.0-beta.1 at the time of this writing.

Here's the list of commands that we can also run:

  • ng test: Run unit tests with karma
  • ng e2e: Run end-to-end tests with protractor
  • ng get: Gets values for project
  • ng set: Sets values for project
  • ng version: Get the version of the CLI
  • ng lint: Run codelyzer to analyze code
  • ng doc: Generate docs for your project
  • ng eject: Get access to the webpack configuration files

Common Scenarios

The Angular CLI team has put together a section of the site called Stories that runs through popuplar real-life scenarios. Give it a look!

https://github.com/angular/angular-cli/wiki/stories

Conclusion

The Angular CLI is an amazing tool and one that comes at a time when more and more people are getting into Angular 2 development. After all the announcments at ng-conf 2016, now is the time to dive in.

The CLI makes diving in that much more accessible since setup, which took up the majority of the time for first-time developers is now handled for us.

Chris Sevilleja

151 posts

Co-founder of Scotch.io. Slapping the keyboard until something good happens.