The Angular CLI is a command line interface for Angular. Its primary purpose is to assist developers with building Angular applications. Angular CLI was introduced together with the second version of Angular. Angular CLI allows you to generate and serving an Angular project as well as generate the Angular files (e.g. components, services, directives, pipes, interfaces, etc).
In order to start your work with Angular CLI you need to install it globally by running,
npm install -g @angular/cli
so you could be able to work with it within any folder.
There are certain pre-requirements which need to be installed first. Angular CLI is dependable on Node 6.9.0 or higher, as well as NPM version 3 or higher.
The simplest way to check which version of the Angular CLI is running on your machine, you can just simply run
ng v
command in the console. As an example output you should be able to see:
1Angular CLI: 1.6.72Node: 8.9.43OS: darwin x64
ng new
Using the Angular CLI makes it easy to create a new Angular application which works, right out of the box. It's worth to mention, that just created project follows the Angular style guide.
Let's see how it works in action. In terminal run
ng new recipe-book
. In this caserecipe-book
is an example project name, you can replace with anything you like.
The application generation process takes few minutes, in order to create components and install node modules. When the project is created, you should see a success message.
1$ ng new recipe-book2create recipe-book/README.md (1027 bytes)3create recipe-book/.angular-cli.json (1247 bytes)4create recipe-book/.editorconfig (245 bytes)5create recipe-book/.gitignore (529 bytes)6create recipe-book/src/assets/.gitkeep (0 bytes)7create recipe-book/src/environments/environment.prod.ts (51 bytes)8create recipe-book/src/environments/environment.ts (387 bytes)9create recipe-book/src/favicon.ico (5430 bytes)10create recipe-book/src/index.html (298 bytes)11create recipe-book/src/main.ts (370 bytes)12create recipe-book/src/polyfills.ts (2405 bytes)13create recipe-book/src/styles.css (80 bytes)14create recipe-book/src/test.ts (642 bytes)15create recipe-book/src/tsconfig.app.json (211 bytes)16create recipe-book/src/tsconfig.spec.json (283 bytes)17create recipe-book/src/typings.d.ts (104 bytes)18create recipe-book/e2e/app.e2e-spec.ts (294 bytes)19create recipe-book/e2e/app.po.ts (208 bytes)20create recipe-book/e2e/tsconfig.e2e.json (235 bytes)21create recipe-book/karma.conf.js (923 bytes)22create recipe-book/package.json (1296 bytes)23create recipe-book/protractor.conf.js (722 bytes)24create recipe-book/tsconfig.json (363 bytes)25create recipe-book/tslint.json (3012 bytes)26create recipe-book/src/app/app.module.ts (316 bytes)27create recipe-book/src/app/app.component.css (0 bytes)28create recipe-book/src/app/app.component.html (1141 bytes)29create recipe-book/src/app/app.component.spec.ts (986 bytes)30create recipe-book/src/app/app.component.ts (207 bytes)31Installing packages for tooling via yarn.32yarn install v1.3.233info No lockfile found.34[1/4] 🔍 Resolving packages...35warning karma > log4js > nodemailer@2.7.2: All versions below 4.0.1 of Nodemailer are deprecated. See https://nodemailer.com/status/36warning karma > log4js > loggly > request > node-uuid@1.4.8: Use uuid module instead37warning karma > log4js > nodemailer > mailcomposer@4.0.1: This project is unmaintained38warning karma > log4js > nodemailer > socks@1.1.9: If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.039warning karma > log4js > nodemailer > mailcomposer > buildmail@4.0.1: This project is unmaintained40warning karma > log4js > mailgun-js > proxy-agent > socks-proxy-agent > socks@1.1.10: If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.041[2/4] 🚚 Fetching packages...42[3/4] 🔗 Linking dependencies...43[4/4] 📃 Building fresh packages...44success Saved lockfile.45✨ Done in 95.28s.46Installed packages for tooling via yarn.47Successfully initialized git.48Project 'recipe-book' successfully created.
Angular CLI creates a folder with the same name as the project name. In our case its recipe-book
. Let's quickly go through the files and folders which were just created.
1recipe-book2├── README.md3├── e2e4├── karma.conf.js5├── node_modules6├── package.json7├── protractor.conf.js8├── src9├── tsconfig.json10├── tslint.json11└── yarn.lock
README.md
which has a basic overview of Angular CLI and available commands you can use.e2e
folder is responsible for end-to-end tests.karma.conf.js
is a config file for Karma which is used for unit testing.node_modules
folder as you might already guess it's a folder where all of the packages and libraries were installed which are defined in package.json
.package.json
is the main place for your project configuration like scripts
and dependencies
.protractor.conf.js
is a config file for Protractor which is used for end-to-end testing.tsconfig.json
is a config file for TypeScript.tslint.json
is a TypeScript linter which checks our code against style rules defined in this file.yarn.lock
or package-lock.json
are the lock files generated by yarn
or npm
depends which tool for installing packages you use.src
folder is the place where in the future you are going to add all new components
, services
, modules
, and other files for your application.1src2├── app3│ ├── app.component.css4│ ├── app.component.html5│ ├── app.component.spec.ts6│ ├── app.component.ts7│ └── app.module.ts8├── assets9├── environments10│ ├── environment.prod.ts11│ └── environment.ts12├── favicon.ico13├── index.html14├── main.ts15├── polyfills.ts16├── styles.css17├── test.ts18├── tsconfig.app.json19├── tsconfig.spec.json20└── typings.d.ts
Structure of the
src
folder is pretty much self-explanatory. But still, let's have a quick look at it.
app
folder is a starting point for our application.environments
is build environments. From a preview, you may notice, that it has two files - environment.prod.ts
and environment.ts
as you might already guess one file is responsible for development
while the other one for production
environment.favicon
which is used as a placeholder and can be replaced later on.index.html
is the first thing the user sees when accessing our application.main.ts
is the core file which responsible for bootstrapping of our application.polyfills.ts
file incorporates the mandatory and many of the optional polyfills as JavaScript import
statements.styles.css
and test.ts
these files are related to applying styles and initialising the Angular testing environment.tsconfig.*.json
files are for TypeScript configuration. tsconfig.app.json
is used for compiling the code, while tsconfig.spec.json
for compiling the tests.typings.d.ts
file provides the required typings for TypeScript.ng serve
Yay, we have just generated a new application, but what we need to do to run it? It's really simple, all you need to do is to run ng serve
in your terminal.
The
ng-serve
command starts a development server which listens on port4200
by default. In case where port4200
is already in use or you want to run it on a different port number, use--port
to specify a different port. Example:$ ng serve --port 1337
Now when the development server is running, open your browser onhttp://localhost:1337/
.
1$ ng serve2** NG Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **3Date: 2018-04-13T09:59:15.362Z l Hash: b1af346cc725e7d9fcb54Time: 7418ms5chunk {inline} inline.bundle.js (inline) 5.79 kB [entry] [rendered]6chunk {main} main.bundle.js (main) 25.8 kB [initial] [rendered]7chunk {polyfills} polyfills.bundle.js (polyfills) 562 kB [initial] [rendered]8chunk {styles} styles.bundle.js (styles) 34 kB [initial] [rendered]9chunk {vendor} vendor.bundle.js (vendor) 7.44 MB [initial] [rendered]10
11webpack: Compiled successfully.
ng generate
Whoa, your application is up and running and can be accessed through the browser. Now it's the time to expand it!
The Angular CLI has a truly awesome command to scaffold new blueprints -
ng generate
orng g
as an alias.
Here is a list of all possible blueprints you can scaffold using ng generate
component
directive
pipe
service
class
guard
interface
enum
module
All you need to do is to run ng g [blueprint-to-scaffold] [your-blueprint-name]
. Let's imagine we need to create a new recipes
component. Then we just run ng g component recipes
.
1$ ng g component recipes2create src/app/recipes/recipes.component.css (0 bytes)3create src/app/recipes/recipes.component.html (26 bytes)4create src/app/recipes/recipes.component.spec.ts (635 bytes)5create src/app/recipes/recipes.component.ts (273 bytes)6update src/app/app.module.ts (402 bytes)
The Angular CLI adds reference to
components
,directives
andpipes
automatically in theapp.module.ts
.
Additionally, it's worth to mention the fact that ng generate
support relative path generation for components. Let's quickly go through the certain amount of options ng generate
offers us. In the first example, we are located in src/app/recipes
:
ng g component recipe
, new component is going to be generated in src/app/recipes/recipe
.ng g component ./recipe
, new component is going to be generated in src/app/recipe
.In the second example, we are located in the src/app
:
ng g component recipes/recipe
, new component is going to be generated in src/app/recipes/recipe
.ng test
Testing your application is a good practice, but often developers tend to ignore this step whenever it's a business or personal projects due to lack of the time or desire.
"Write your ******* tests, always" — Mattias Petter Johansson
The Angular CLI is doing a great job at simplifying the developer lives by auto-generating testing files for us. The Angular CLI offers you unit and end-to-end testing. To run unit tests, open the terminal and run ng test
. This step builds the Angular application and runs the test runner. You should see two different outputs: output in a console and browsers which was launched by Karma test runner.
1$ ng test210% building modules 1/1 modules 0 active13 04 2018 09:18:54.509:WARN [karma]: No captured browser, open http://localhost:9876/313 04 2018 09:18:54.515:INFO [karma]: Front-end scripts not present. Compiling...413 04 2018 09:19:00.730:WARN [karma]: No captured browser, open http://localhost:9876/513 04 2018 09:19:00.995:INFO [karma]: Karma v2.0.0 server started at http://0.0.0.0:9876/613 04 2018 09:19:00.995:INFO [launcher]: Launching browser Chrome with unlimited concurrency713 04 2018 09:19:01.000:INFO [launcher]: Starting browser Chrome813 04 2018 09:19:02.686:INFO [Chrome 65.0.3325 (Mac OS X 10.13.3)]: Connected on socket jISkDcWPkf6iDQRWAAAA with id 625751739Chrome 65.0.3325 (Mac OS X 10.13.3): Executed 0 of 4 SUCCESS (0 secs / 0 secChrome 65.0.3325 (Mac OS X 10.13.3): Executed 1 of 4 SUCCESS (0 secs / 0.151Chrome 65.0.3325 (Mac OS X 10.13.3): Executed 2 of 4 SUCCESS (0 secs / 0.203Chrome 65.0.3325 (Mac OS X 10.13.3): Executed 3 of 4 SUCCESS (0 secs / 0.238Chrome 65.0.3325 (Mac OS X 10.13.3): Executed 4 of 4 SUCCESS (0 secs / 0.283Chrome 65.0.3325 (Mac OS X 10.13.3): Executed 4 of 4 SUCCESS (0.328 secs / 0.283 secs)
The same procedure goes for running end-to-end tests using protractor. You just run the ng e2e
in a terminal.
1$ ng e2e2** NG Live Development Server is listening on localhost:49152, open your browser on http://localhost:49152/ **3Date: 2018-04-13T08:29:04.113Z l Hash: 8a08417e4497e11cece34Time: 7613ms5chunk {inline} inline.bundle.js, inline.bundle.js.map (inline) 5.83 kB [entry] [rendered]6chunk {main} main.bundle.js, main.bundle.js.map (main) 11.1 kB [initial] [rendered]7chunk {polyfills} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 203 kB [initial] [rendered]8chunk {styles} styles.bundle.js, styles.bundle.js.map (styles) 11.4 kB [initial] [rendered]9chunk {vendor} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.76 MB [initial] [rendered]10(node:30726) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.11
12webpack: Compiled successfully.13[09:29:04] I/file_manager - creating folder /Users/edvinsantonovs/Documents/repos/recipe-book/node_modules/webdriver-manager/selenium14[09:29:05] I/update - chromedriver: unzipping chromedriver_2.37.zip15[09:29:05] I/update - chromedriver: setting permissions to 0755 for /Users/edvinsantonovs/Documents/repos/recipe-book/node_modules/webdriver-manager/selenium/chromedriver_2.3716[09:29:05] I/launcher - Running 1 instances of WebDriver17[09:29:05] I/direct - Using ChromeDriver directly...18Jasmine started19
20 recipe-book App21 ✓ should display welcome message22
23Executed 1 of 1 spec SUCCESS in 0.685 sec.
In this case, the browser pops up, executes the application and dismiss once again after a short moment.
ng lint
When you start a new project with ng new
, Angular CLI automatically generates a tslint.json
with the set of rules of best practices for Angular. You can change them to suit your needs.
1{2 "rulesDirectory": [3 "node_modules/codelyzer"4 ],5 "rules": {6 "arrow-return-shorthand": true,7 "callable-types": true,8 "class-name": true,9 "comment-format": [10 true,11 "check-space"12 ],13 "curly": true,14 "deprecation": {15 "severity": "warn"16 },17 "eofline": true,18 "forin": true,19 "import-blacklist": [20 true,21 "rxjs",22 "rxjs/Rx"23 ],24 "import-spacing": true,25 "indent": [26 true,27 "spaces"28 ],29 ...30 }31}
To check if your project has any linting problems, just run ng lint
in the terminal.
In the majority of the cases, you will either see that all files successfully passed linting
1$ ng lint23All files pass linting.or you will have a list of the files with lint error and description
1$ ng lint23ERROR: ../recipe-book/src/app/app.module.ts[1, 31]: " should be '4ERROR: ../recipe-book/src/app/app.module.ts[2, 26]: " should be '5ERROR: ../recipe-book/src/app/app.module.ts[4, 30]: " should be '6ERROR: ../recipe-book/src/app/app.module.ts[5, 34]: " should be '78Lint errors found in the listed files.
ng build
Last but not the least command of the Angular CLI — ng build
.
The
ng build
command compiles the application into an output directory.
1$ ng build2Date: 2018-04-13T09:25:33.673Z l Hash: d08ebffadf328ed32e553Time: 7260ms4chunk {inline} inline.bundle.js, inline.bundle.js.map (inline) 5.83 kB [entry] [rendered]5chunk {main} main.bundle.js, main.bundle.js.map (main) 10.3 kB [initial] [rendered]6chunk {polyfills} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 203 kB [initial] [rendered]7chunk {styles} styles.bundle.js, styles.bundle.js.map (styles) 11.4 kB [initial] [rendered]8chunk {vendor} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.44 MB [initial] [rendered]
When the building is finished, you can find your application in the /dist
directory.
1dist2├── favicon.ico3├── index.html4├── inline.bundle.js5├── inline.bundle.js.map6├── main.bundle.js7├── main.bundle.js.map8├── polyfills.bundle.js9├── polyfills.bundle.js.map10├── styles.bundle.js11├── styles.bundle.js.map12├── vendor.bundle.js13└── vendor.bundle.js.map
We just built our project, and you already can see the difference between the build and source code. The built project which is located in /dist
looks tiny compared to the source code. That's great isn't it, but hold on there is one more trick!
By default, the
development
build target and environment are used.
Luckily enough, ng build
offers us an option to specify build target(--target=production
or --target=development
) and environment file to be used with that build(--environment=dev
or --environment=prod
). Let's run production build by typing ng build --prod
in a terminal. Whoa! It made our /dist
folder even smaller with only a few files are left there.
1dist2├── 3rdpartylicenses.txt3├── favicon.ico4├── index.html5├── inline.ba64e9064e468420379a.bundle.js6├── main.e41bc4358dddb8b53359.bundle.js7├── polyfills.46af3f84a403e219371b.bundle.js8└── styles.9c0ad738f18adc3d19ed.bundle.css
You might notice, several things:
*.map
generated files.Hashes in the file names are used as a part of the cache-busting technique. Every time we do the changes to our application, we need to redeploy the application to the server. In order to prevent our files to be cached on the server we add hashes to the file names. On every run of
ng build --prod
command, compiler randomly changes the hashes, so the server would treat the changed files as new ones.
Here is a list of tips I came across which might simplify your work with Angular CLI.
ng new --skip-install
. Don't forget to install node modules later on.ng new --style [scss | sass | less | styl]
.ng g c [your-blueprint-name]
.ng g c [your-blueprint-name] --spec false
.ng test --code-coverage
. The coverage report will be in the /coverage
directory.Sign up to get updates when I write something new. No spam ever.
Subscribe to my Newsletter