feat(cli-quickstart): add updated cli-quickstart (#3112)

* feat(cli-quickstart): add updated cli-quickstart

* incorporate Ward's feedback
This commit is contained in:
Filipe Silva 2017-01-23 23:44:55 +00:00 committed by GitHub
parent 9fb5e0ad24
commit 0143d8f454
41 changed files with 521 additions and 464 deletions

View File

@ -17,7 +17,7 @@
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
"test:webpack": "karma start karma.webpack.conf.js",
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
"build:cli": "ng build",
"build:cli": "ng build --no-progress",
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
"build:babel": "babel app -d app --extensions \".es6\" --source-maps",
"copy-dist-files": "node ./copy-dist-files.js",
@ -27,6 +27,8 @@
"author": "",
"license": "MIT",
"dependencies": {},
"devDependencies": {},
"devDependencies": {
"angular-cli": "^1.0.0-beta.26"
},
"repository": {}
}

View File

@ -1,4 +1,4 @@
'use strict'; // necessary for es6 output in node
'use strict'; // necessary for es6 output in node
import { browser, element, by } from 'protractor';
@ -8,7 +8,7 @@ describe('cli-quickstart App', () => {
});
it('should display message saying app works', () => {
let pageTitle = element(by.css('cli-quickstart-app h1')).getText();
let pageTitle = element(by.css('app-root h1')).getText();
expect(pageTitle).toEqual('My First Angular App');
});
});

View File

@ -6,10 +6,21 @@
# dependencies
/node_modules
/bower_components
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
# IDE - VSCode
.vscode/
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
@ -18,6 +29,7 @@
/libpeerconnection.log
npm-debug.log
testem.log
/typings
# e2e
/e2e/*.js
@ -27,12 +39,4 @@ testem.log
.DS_Store
Thumbs.db
# angular.io overrides
!angular-cli.json
!angular-cli-build.js
!config/environment.js
!config/karma-test.js
!config/karma.conf.js
!config/protractor.conf.js
!src/typings.d.ts
!src/tsconfig.json
!src/styles.css

View File

@ -0,0 +1,31 @@
# MyApp
This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.25.5.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
Before running the tests make sure you are serving the app via `ng serve`.
## Deploying to GitHub Pages
Run `ng github-pages:deploy` to deploy to GitHub Pages.
## Further help
To get more help on the `angular-cli` use `ng help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@ -1,16 +0,0 @@
/* global require, module */
var Angular2App = require('angular-cli/lib/broccoli/angular2-app');
module.exports = function(defaults) {
return new Angular2App(defaults, {
vendorNpmFiles: [
'systemjs/dist/system-polyfills.js',
'systemjs/dist/system.src.js',
'zone.js/dist/**/*.+(js|js.map)',
'es6-shim/es6-shim.js',
'rxjs/**/*.+(js|js.map)',
'@angular/**/*.+(js|js.map)'
]
});
};

View File

@ -1,31 +1,59 @@
{
"project": {
"version": "1.0.0-beta.5",
"name": "cli-quickstart"
"version": "1.0.0-beta.25.5",
"name": "my-app"
},
"apps": [
{
"main": "src/main.ts",
"tsconfig": "src/tsconfig.json",
"mobile": false
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"test": "test.ts",
"tsconfig": "tsconfig.json",
"prefix": "app",
"mobile": false,
"styles": [
"styles.css"
],
"scripts": [],
"environments": {
"source": "environments/environment.ts",
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"addons": [],
"packages": [],
"e2e": {
"protractor": {
"config": "config/protractor.conf.js"
"config": "./protractor.conf.js"
}
},
"test": {
"karma": {
"config": "config/karma.conf.js"
"config": "./karma.conf.js"
}
},
"defaults": {
"prefix": "app",
"sourceDir": "src",
"styleExt": "css",
"prefixInterfaces": false
"prefixInterfaces": false,
"inline": {
"style": false,
"template": false
},
"spec": {
"class": false,
"component": true,
"directive": true,
"module": false,
"pipe": true,
"service": true
}
}
}

View File

@ -1,3 +0,0 @@
export const environment = {
production: false
};

View File

@ -1,10 +0,0 @@
/* jshint node: true */
module.exports = function(environment) {
return {
environment: environment,
baseURL: '/',
locationType: 'auto'
};
};

View File

@ -1,41 +0,0 @@
module.exports = function (config) {
config.set({
basePath: '..',
frameworks: ['jasmine'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher')
],
customLaunchers: {
// chrome setup for travis CI using chromium
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
files: [
{ pattern: 'dist/vendor/es6-shim/es6-shim.js', included: true, watched: false },
{ pattern: 'dist/vendor/zone.js/dist/zone.js', included: true, watched: false },
{ pattern: 'dist/vendor/systemjs/dist/system-polyfills.js', included: true, watched: false },
{ pattern: 'dist/vendor/systemjs/dist/system.src.js', included: true, watched: false },
{ pattern: 'dist/vendor/zone.js/dist/async-test.js', included: true, watched: false },
{ pattern: 'config/karma-test-shim.js', included: true, watched: true },
// Distribution folder.
{ pattern: 'dist/**/*', included: false, watched: true }
],
exclude: [
// Vendor packages might include spec files. We don't want to use those.
'dist/vendor/**/*.spec.js'
],
preprocessors: {},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};

View File

@ -1,29 +0,0 @@
/*global jasmine */
var SpecReporter = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'../e2e/**/*.e2e.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
useAllAngular2AppRoots: true,
beforeLaunch: function() {
require('ts-node').register({
project: 'e2e'
});
},
onPrepare: function() {
jasmine.getEnv().addReporter(new SpecReporter());
}
};

View File

@ -0,0 +1,14 @@
import { MyAppPage } from './app.po';
describe('my-app App', function() {
let page: MyAppPage;
beforeEach(() => {
page = new MyAppPage();
});
it('should display message saying app works', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('app works!');
});
});

View File

@ -1,14 +0,0 @@
import { CliQuickstartPage } from './app.po';
describe('cli-quickstart App', function() {
let page: CliQuickstartPage;
beforeEach(() => {
page = new CliQuickstartPage();
});
it('should display message saying app works', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('cli-quickstart works!');
});
});

View File

@ -1,9 +1,11 @@
export class CliQuickstartPage {
import { browser, element, by } from 'protractor';
export class MyAppPage {
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.css('cli-quickstart-app h1')).getText();
return element(by.css('app-root h1')).getText();
}
}

View File

@ -0,0 +1,3 @@
<h1>
{{title}}
</h1>

View File

@ -0,0 +1,35 @@
/* tslint:disable:no-unused-variable */
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
});
TestBed.compileComponents();
});
it('should create the app', async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
it(`should have as title 'app works!'`, async(() => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('app works!');
}));
it('should render title in a h1 tag', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('app works!');
}));
});

View File

@ -4,14 +4,13 @@ import { Component } from '@angular/core';
// #docregion metadata
@Component({
moduleId: module.id,
selector: 'cli-quickstart-app',
templateUrl: './cli-quickstart.component.html',
styleUrls: ['./cli-quickstart.component.css']
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
// #enddocregion metadata
// #docregion title, class
export class CliQuickstartAppComponent {
export class AppComponent {
title = 'My First Angular App';
}
// #enddocregion title, class

View File

@ -0,0 +1,20 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -1,2 +0,0 @@
<!-- #docregion -->
<h1>{{title}}</h1>

View File

@ -1,22 +0,0 @@
import {
beforeEachProviders,
describe,
expect,
it,
inject
} from '@angular/core/testing';
import { CliQuickstartAppComponent } from '../app/cli-quickstart.component';
beforeEachProviders(() => [CliQuickstartAppComponent]);
describe('App: CliQuickstart', () => {
it('should create the app',
inject([CliQuickstartAppComponent], (app: CliQuickstartAppComponent) => {
expect(app).toBeTruthy();
}));
it('should have as title \'cli-quickstart works!\'',
inject([CliQuickstartAppComponent], (app: CliQuickstartAppComponent) => {
expect(app.title).toEqual('cli-quickstart works!');
}));
});

View File

@ -1,7 +0,0 @@
// The file for the current environment will overwrite this one during build
// Different environments can be found in config/environment.{dev|prod}.ts
// The build system defaults to the dev environment
export const environment = {
production: false
};

View File

@ -1,2 +0,0 @@
export * from './environment';
export * from './cli-quickstart.component';

View File

@ -0,0 +1,8 @@
// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `angular-cli.json`.
export const environment = {
production: false
};

View File

@ -1,35 +1,14 @@
<!-- #docplaster -->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CliQuickstart</title>
<title>MyApp</title>
<base href="/">
{{#unless environment.production}}
<script src="/ember-cli-live-reload.js" type="text/javascript"></script>
{{/unless}}
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<!-- #docregion body -->
<body>
<cli-quickstart-app>Loading...</cli-quickstart-app>
<!-- #enddocregion body -->
{{#each scripts.polyfills}}<script src="{{.}}"></script>{{/each}}
<!-- #docregion import -->
<script>
System.import('system-config.js').then(function () {
System.import('main');
}).catch(console.error.bind(console));
</script>
<!-- #enddocregion import -->
<!-- #docregion body -->
<app-root>Loading...</app-root>
</body>
<!-- #enddocregion body -->
</html>

View File

@ -1,18 +1,12 @@
// #docplaster
// #docregion important
import { bootstrap } from '@angular/platform-browser-dynamic';
import './polyfills.ts';
// #enddocregion important
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './app/';
// #docregion important
import { CliQuickstartAppComponent } from './app/';
// #enddocregion important
import { environment } from './environments/environment';
import { AppModule } from './app/app.module';
if (environment.production) {
enableProdMode();
}
// #docregion important
bootstrap(CliQuickstartAppComponent);
// #enddocregion important
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -0,0 +1,19 @@
// This file includes polyfills needed by Angular and is loaded before
// the app. You can add your own extra polyfills to this file.
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
import 'zone.js/dist/zone';

View File

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

View File

@ -1,54 +0,0 @@
/***********************************************************************************************
* User Configuration.
**********************************************************************************************/
/** Map relative paths to URLs. */
const map: any = {
};
/** User packages configuration. */
const packages: any = {
};
////////////////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************************
* Everything underneath this line is managed by the CLI.
**********************************************************************************************/
const barrels: string[] = [
// Angular specific barrels.
'@angular/core',
'@angular/common',
'@angular/compiler',
'@angular/http',
'@angular/router',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
// Thirdparty barrels.
'rxjs',
// App specific barrels.
'app',
'app/shared',
/** @cli-barrel */
];
const cliSystemConfigPackages: any = {};
barrels.forEach((barrelName: string) => {
cliSystemConfigPackages[barrelName] = { main: 'index' };
});
/** Type declaration for ambient System. */
declare var System: any;
// Apply the CLI SystemJS configuration.
System.config({
map: {
'@angular': 'vendor/@angular',
'rxjs': 'vendor/rxjs',
'main': 'main.js'
},
packages: cliSystemConfigPackages
});
// Apply the user's configuration.
System.config({ map, packages });

View File

@ -0,0 +1,32 @@
import './polyfills.ts';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
declare var require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function () {};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();

View File

@ -1,22 +1,18 @@
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "",
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"lib": ["es6", "dom"],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": false,
"outDir": "../dist/",
"rootDir": ".",
"outDir": "../dist/out-tsc",
"sourceMap": true,
"target": "es5",
"inlineSources": true
},
"files": [
"main.ts",
"typings.d.ts"
]
"typeRoots": [
"../node_modules/@types"
]
}
}

View File

@ -40,6 +40,7 @@
"@types/angular-sanitize": "^1.3.3",
"@types/jasmine": "~2.5.36",
"@types/node": "^6.0.45",
"angular-cli": "^1.0.0-beta.26",
"angular2-template-loader": "^0.6.0",
"awesome-typescript-loader": "^3.0.0-beta.18",
"babel-cli": "^6.16.0",

View File

@ -37,6 +37,7 @@
- var basics = sections('guide', function(item) { return item.basics; });
- var guide = sections('guide', function(item) { return !item.basics; });
- var qs = sections('', function(item) { return item.slug === 'quickstart'; })[0] || {};
- var cliqs = sections('', function(item) { return item.slug === 'cli-quickstart'; })[0] || {};
- var reference = sections('', function(item) { return item.reference; });
- var anyItemSelected = function(items) {
- var selectedCount = items.filter(function(item) { return !!item.class; }).length;
@ -47,6 +48,11 @@
- var bit = splitted[splitted.length - 1].replace('.html', '');
- return bit === 'quickstart' ? 'is-selected' : '';
-}
- var isCLIQuickstartSelected = function() {
- var split = cur.split('/');
- var bit = split[split.length - 1].replace('.html', '');
- return bit === 'cli-quickstart' ? 'is-selected' : '';
-}
- var isApiReferenceSelected = function() {
- var splitted = cur.split('/');
- var bit = splitted[splitted.length - 2];
@ -79,6 +85,9 @@ nav(class="sidenav l-pinned-left l-layer-4 l-offset-nav" data-swiftype-index="f
li.sidenav-section
a(class="nav-title #{isQuickstartSelected(cur)}" href="#{qs.href}" title="#{qs.tooltip}") Quickstart
li.sidenav-section
a(class="nav-title #{isCLIQuickstartSelected(cur)}" href="#{cliqs.href}" title="#{cliqs.tooltip}") CLI Quickstart
li.sidenav-section
a(class="nav-title is-parent #{anyItemSelected(basics)}" href="#{basics[0].href}" title="#{basics[0].tooltip}") Guide
@ -137,4 +146,4 @@ script.
sideNav.scrollTop = link.offsetTop - (window.innerHeight/2);
//alert("offsetTop: " + link.offsetTop + " side-nav top is " + sideNav.scrollTop);
}
})()
})()

View File

@ -7,14 +7,6 @@
"banner": "The latest Angular release is <b>2.4</b>. Learn about the latest <a href='guide/change-log.html' title='Documentation change log'>updates to the documentation</a>. View the <a href='https://github.com/angular/angular/blob/master/CHANGELOG.md' target='_blank' title='Angular Product Changes'>Angular change log</a> for enhancements, fixes, and breaking changes in Angular itself."
},
"cli-quickstart": {
"icon": "query-builder",
"title": "CLI Quickstart",
"subtitle": "TypeScript",
"description": "Use the CLI tool to quickly build Angular applications",
"hide": true
},
"quickstart": {
"icon": "query-builder",
"title": "Quickstart",
@ -22,6 +14,13 @@
"banner": "A quick look at Angular basics"
},
"cli-quickstart": {
"icon": "query-builder",
"title": "CLI Quickstart",
"subtitle": "TypeScript",
"banner": "Use the CLI tool to quickly build Angular applications"
},
"tutorial": {
"icon": "list",
"title": "Tutorial",

View File

@ -2,7 +2,7 @@ include _util-fns
:marked
Good tools make application development quicker and easier to maintain than
if we did everything by hand.
if you did everything by hand.
The [**Angular-CLI**](https://cli.angular.io/) is a **_command line interface_** tool
that can create a project, add files, and perform a variety of on-going development tasks such
@ -13,10 +13,10 @@ include _util-fns
while adhering to the [Style Guide](./guide/style-guide.html) recommendations that
benefit _every_ Angular project.
By the end of the chapter, we'll have a basic understanding of development with the CLI
By the end of the chapter, you'll have a basic understanding of development with the CLI
and a foundation for both these documentation samples and our real world applications.
We'll pursue these ends in the following high-level steps:
You'll pursue these ends in the following high-level steps:
1. [Set up](#devenv) the development environment
2. [Create](#create-proj) a new project and skeleton application
@ -27,39 +27,31 @@ include _util-fns
.l-main-section
h2#devenv Step 1. Set up the Development Environment
:marked
We need to set up our development environment before we can do anything.
You need to set up our development environment before you can do anything.
Install **[Node.js® and npm](https://nodejs.org/en/download/)**
if they are not already on your machine.
.l-sub-section
:marked
**Verify that you are running node `v4.x.x` and npm `3.x.x`**
**Verify that you are running at least node `4.x.x` and npm `3.x.x`**
by running `node -v` and `npm -v` in a terminal/console window.
Older versions produce errors.
Older versions produce errors, but newer versions are fine.
:marked
Then **install the [Angular-CLI](https://github.com/angular/angular-cli)** globally.
code-example(format="").
code-example(language="sh" class="code-shell").
npm install -g angular-cli
.l-main-section
h2#create-project Step 2. Create a new project
:marked
Open a terminal window.
.alert.is-important
:marked
_Windows Developers_: open a console window _as an **administrator**_.
The Angular-CLI build steps later in this tutorial
create <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680(v=vs.85).aspx" target="_blank"><i>symbolic links</i></a>
to various directories. These so-called _symlinks_ save time and space.
But it takes administrator rights under Windows to create them.
:marked
Generate a new project and skeleton application by running the following commands:
code-example(format="").
ng new cli-quickstart
code-example(language="sh" class="code-shell").
ng new my-app
.l-sub-section
:marked
@ -70,12 +62,14 @@ code-example(format="").
h2#serve Step 3: Serve the application
:marked
Go to the project directory and launch the server.
code-example(format="").
cd cli-quickstart
code-example(language="sh" class="code-shell").
cd my-app
ng serve
:marked
The `ng serve` command launches the server, watches our files,
and rebuilds the app as we make changes to the files.
and rebuilds the app as you make changes to the files.
Open a browser on `http://localhost:4200/`; the app greets us with a message:
@ -86,29 +80,23 @@ figure.image-display
h2#first-component Step 4: Edit our first Angular component
:marked
The CLI created our first Angular component for us.
This is the _root component_ and it is named after the project. We created the project
with the name `cli-quickstart` so our component is `CliQuickstartAppComponent` and
it's in the file `/src/app/cli-quickstart.component.ts`
.l-sub-section
:marked
_CliQuickstartAppComponent_ is a _horrible name_. Almost everyone renames it to _AppComponent_ ...
and renames all of the associated files to _app.component.??_ as we do throughout the documentation.
We'll leave that step as an exercise.
This is the _root component_ and it is named `app-root`.
You can find it in `./src/app/app.component.ts`.
:marked
Open the component file and change the `title` property from _cli-quickstart works!_ to _My First Angular App_:
Open the component file and change the `title` property from _app works!_ to _My First Angular App_:
+makeExample('cli-quickstart/ts/src/app/cli-quickstart.component.ts', 'title', 'src/app/cli-quickstart.component.ts')(format=".")
+makeExample('cli-quickstart/ts/src/app/app.component.ts', 'title', 'src/app/app.component.ts')(format=".")
:marked
The browser reloads automatically and we see the revised title. That's nice, but we can make it look better.
Open `src/app/cli-quickstart.component.css` and give our component some style
+makeExample('cli-quickstart/ts/src/app/cli-quickstart.component.css', null, 'src/app/cli-quickstart.component.css')(format=".")
+makeExample('cli-quickstart/ts/src/app/app.component.css', null, 'src/app/app.component.css')(format=".")
figure.image-display
img(src='/resources/images/devguide/cli-quickstart/hello-angular.png' alt="Output of QuickStart app")
img(src='/resources/images/devguide/cli-quickstart/my-first-app.png' alt="Output of QuickStart app")
:marked
Looking good!
@ -116,163 +104,256 @@ figure.image-display
.l-main-section
:marked
## What's next?
Our first application doesn't do much. It's basically "Hello, World" for Angular.
That's about all you'd expect to do in a "Hello, World" app.
We kept it simple in our first pass: we wrote our first Angular application using the angular CLI
and modified our first component. That's about all we'd expect to do for a "Hello, World" app.
You're ready to take the [Tour of Heroes Tutorial](./tutorial) and build
a small application that demonstrates the great things you can build with Angular.
**We have greater ambitions!**
:marked
We're about to take the next step and build a small application that
demonstrates the great things we can build with Angular.
Or you can stick around a bit longer to learn about the files in your brand new project.
Join us on the [Tour of Heroes Tutorial](./tutorial)!
Or stick around a bit longer to learn a few things about what we just did.
<br><br>
.l-main-section
h1#behind-the-code Behind the code
:marked
### CliQuickstartAppComponent is the root of the application
## Project file review
Every Angular app has at least one **root component**, that hosts the client user experience.
Components are the basic building blocks of Angular applications.
A component controls a portion of the screen &mdash; a *view* &mdash; through its associated template.
An Angular-CLI project is the foundation for both quick experiments and enterprise solutions.
This QuickStart has only one, extremely simple component.
But it has the essential structure of every component we'll ever write:
The first file you should check out is `README.md`.
It has some basic information on how to use CLI commands.
Whenever you want to know more about how Angular-CLI works make sure to visit
[the Angular-CLI repository](https://github.com/angular/angular-cli) and
[Wiki](https://github.com/angular/angular-cli/wiki).
* one or more [import](#component-import)
statements to reference the things we need.
* a [@Component decorator](#component-decorator)
that tells Angular what template to use and how to create the component.
* a [component class](#component-class)
that controls the appearance and behavior of a view through its template.
Some of the generated files might be unfamiliar to you.
a#component-import
:marked
### Import
block src-files
:marked
### The `src` folder
Your app lives in the `src` folder.
All Angular components, templates, styles, images and anything else your app needs go here.
Any files outside of this folder are meant to support building your app.
Angular apps are modular. They consist of many files, each dedicated to a purpose.
.filetree
.file src
.children
.file app
.children
.file app.component.css
.file app.component.html
.file app.component.spec.ts
.file app.component.ts
.file app.module.ts
.file assets
.children
.file .gitkeep
.file environments
.children
.file environment.prod.ts
.file environment.ts
.file favicon.ico
.file index.html
.file main.ts
.file polyfills.ts
.file styles.css
.file test.ts
.file tsconfig.json
Angular itself is modular. It is a collection of library modules
consisting of several, related features that we'll use to build our application.
style td, th {vertical-align: top}
table(width="100%")
col(width="20%")
col(width="80%")
tr
th File
th Purpose
tr
td <code>app/app.component.{ts,html,css,spec.ts}</code>
td
:marked
Defines the `AppComponent` along with an HTML template, CSS stylesheet and a unit test.
It is the **root** component of what will become a tree of nested components
as the application evolves.
tr
td <code>app/app.module.ts</code>
td
:marked
Defines `AppModule`, the [root module](guide/appmodule.html "AppModule: the root module")
that tells Angular how to assemble the application.
Right now it declares only the `AppComponent`.
Soon there will be more components to declare.
tr
td <code>assets/*</code>
td
:marked
A folder where you can put images and anything else you need to be copied wholesale
when you build your application.
tr
td <code>environments/*</code>
td
:marked
This folder contains one file for each of your destination environments,
each exporting simple configuration variables to use on your application.
The files will be replaced on-the-fly when you build your app.
You might use a different API endpoint for development than you do for production.
Or maybe different analytics tokens.
Maybe even some mock services.
Either way, the CLI has you covered.
tr
td <code>favicon.ico</code>
td
:marked
Every site wants to look good on the bookmark bar.
Get started with your very own Angular icon.
tr
td <code>index.html</code>
td
:marked
The main html page that is served when someone visits your site.
Most of the time you'll never need to edit it.
The CLI will automatically add all `js` and `css` files when building your app so you
never need to add any `<script>` or `<link>` tags here manually.
tr
td <code>main.ts</code>
td
:marked
The main entry point for your app.
Compiles the application with the [JiT compiler](glossary.html#jit)
and [bootstraps](guide/appmodule.html#main "bootstrap the application")
the application to run in the browser.
You can also use the [AoT compiler](glossary.html#ahead-of-time-aot-compilation)
without changing any code by passing on `--aot` to `ng build` or `ng serve`.
tr
td <code>polyfills.ts</code>
td
:marked
Different browsers have different levels of support of the web standards.
Polyfills help normalize those differences.
You should be pretty safe with `core-js` and `zone.js`, but be sure to check out
the [Browser Support guide](guide/browser-support.html) for more information.
tr
td <code>styles.css</code>
td
:marked
Your global styles go here.
Most of the time you'll want to have local styles in your components for easier maintenance,
but styles that affect all of your app need to be in a central place.
tr
td <code>test.ts</code>
td
:marked
This is the main entry point for your unit tests.
It has some custom configuration that might be unfamiliar, but it's not something you'll
need to edit.
tr
td <code>tsconfig.json</code>
td
:marked
Configuration for the TypeScript compiler.
When we need something from a module or library, we import it.
Here we import the `Component` decorator from the Angular **_core_** library
that we'll use as a decorator (`@Component`) to attach metadata to our component class.
.
+makeExcerpt('src/app/cli-quickstart.component.ts', 'import')
block root-files
:marked
### The root folder
The `src/` folder is just one of the items inside the project's root folder.
Other files help you build, test, maintain, document, and deploy the app.
These files go in the root folder next to `src/`.
h3#component-decorator @Component decorator
:marked
`Component` is a *decorator* function that associates Angular *metadata* with a
component class.
The metadata tell Angular how to create and display instances of this component.
.filetree
.file my-app
.children
.file e2e
.children
.file app.e2e-spec.ts
.file app.po.ts
.file tsconfig.json
.file node_modules/...
.file src/...
.file .editorconfig
.file .gitignore
.file angular-cli.json
.file karma.conf.js
.file package.json
.file protractor.conf.js
.file README.md
.file tslint.json
We apply this function to the component class by prefixing the function name with the
**@** symbol and invoking it with a metadata object, just above the class.
style td, th {vertical-align: top}
table(width="100%")
col(width="20%")
col(width="80%")
tr
th File
th Purpose
tr
td <code>e2e/*</code>
td
:marked
Inside `e2e/` live the End-to-End tests.
They shouldn't be inside `src/` because e2e tests are really a separate app that
just so happens to test your main app.
That's why it they even have their own `tsconfig.json`.
tr
td <code>node_modules/...</code>
td
:marked
`Node.js` creates this folder and puts all third party modules listed in
`package.json` inside of it.
tr
td <code>.editorconfig</code>
td
:marked
Simple configuration for your editor to make sure everyone that uses your project
has the same basic configuration.
Most editors support an `.editorconfig` file.
See http://editorconfig.org for more information.
tr
td <code>.gitignore</code>
td
:marked
Git configuration to make sure autogenerated files are not commited to source control.
tr
td <code>angular-cli.json</code>
td
:marked
Configuration for Angular-CLI.
In this file you can set several defaults and also configure what files are included
when your project is build.
Check out the official documentation if you want to know more.
tr
td <code>karma.conf.js</code>
td
:marked
Unit test configuration for the [Karma test runner](https://karma-runner.github.io),
used when running `ng test`.
tr
td <code>package.json</code>
td
:marked
`npm` configuration listing the third party packages your project uses.
You can also add your own [custom scripts](https://docs.npmjs.com/misc/scripts) here.
tr
td <code>protractor.conf.js</code>
td
:marked
End-to-end test configuration for [Protractor](http://www.protractortest.org/),
used when running `ng e2e`.
tr
td <code>README.md</code>
td
:marked
Basic documentation for your project, pre-filled with CLI command information.
Make sure to enhance it with project documentation so that anyone
checking out the repo can build your app!
tr
td <code>tslint.json</code>
td
:marked
Linting configuration for [TSLint](https://palantir.github.io/tslint/) together with
[Codelyzer](http://codelyzer.com/), used when running `ng lint`.
Linting helps keep your code style consistent.
.l-sub-section
:marked
### Next Step
+makeExcerpt('src/app/cli-quickstart.component.ts', 'metadata')
:marked
This particular metadata object has four fields, a `moduleId`, a `selector` a `templateUrl` and an array of `styleUrls`.
The **moduleId** specifies the location of _this_ component definition file
so that Angular can find the corresponding _template_ and _style_ files with URLs that
are relative to this component file.
The module loader sets the value of `module.id` at runtime;
we're using that value to set the metadata `moduleId` property.
The **selector** is a [CSS selector](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
identifying the HTML element that represents this component.
The element tag name for this component is `cli-quickstart-app`.
Angular creates and displays an instance of our `CliQuickstartAppComponent`
wherever it encounters a `<cli-quickstart-app>` element in the host HTML.
The **templateUrl** locates the component's companion template HTML file.
The template tells Angular how to render this component's view.
Our template is a single `<h1>` element surrounding some peculiar Angular data binding syntax.
+makeExample('src/app/cli-quickstart.component.html', null, 'src/app/cli-quickstart.component.html')(format='.')
:marked
The `{{title}}` is an _interpolation_ binding that causes Angular to display the component's
`title` property. After out edit, Angular displays "Hello Angular".
We'll learn more about data binding as we read through the documentation.
The **styleUrls** array specifies the location(s) of the component's private CSS style file(s).
The CLI generated an empty file for us and we added styles to it.
:marked
### Component class
At the bottom of the component definition file is the component class named `CliQuickstartAppComponent`.
+makeExcerpt('cli-quickstart/ts/src/app/cli-quickstart.component.ts', 'class')
:marked
This class contains the `title` property that we're displaying in our template.
We can expand this class with more properties and application logic.
We **export** `CliQuickstartAppComponent` so that we can **import** it elsewhere in our application ... as we're about to do.
:marked
### The *main.ts* file
How does Angular know what to do with our component? We have to tell it.
We _bootstrap_ our application in the file `main.ts`.
+makeExcerpt('src/main.ts', 'important')
:marked
We import the two things we need to launch the application:
1. Angular's browser `bootstrap` function
1. The application root component, `CliQuickstartAppComponent`.
Then we call `bootstrap` with `CliQuickstartAppComponent`.
### Bootstrapping is platform-specific
Notice that we import the `bootstrap` function from `@angular/platform-browser-dynamic`,
not `@angular/core`.
Bootstrapping isn't core because there isn't a single way to bootstrap the app.
True, most applications that run in a browser call the bootstrap function from
this library.
But it is possible to load a component in a different environment.
We might load it on a mobile device with [Apache Cordova](https://cordova.apache.org/) or [NativeScript](https://www.nativescript.org/).
We might wish to render the first page of our application on the server
to improve launch performance or facilitate
[SEO](http://www.google.com/webmasters/docs/search-engine-optimization-starter-guide.pdf).
These targets require a different kind of bootstrap function that we'd import from a different library.
### Why create a *main.ts* file?
Both `main.ts` and the application component files are tiny.
This is just a QuickStart.
We could have merged these two files into one
and spared ourselves some complexity.
We'd rather demonstrate the proper way to structure an Angular application.
App bootstrapping is a separate concern from presenting a view.
Mixing concerns creates difficulties down the road.
We might launch the `CliQuickstartAppComponent` in multiple environments with different bootstrappers.
Testing the component is much easier if it doesn't also try to run the entire application.
Let's make the small extra effort to do it *the right way*.
### Loading the application with SystemJS
The CLI uses `System.js` to load the application. We just need to call `System.import` and pass it our `main.ts`
file to boot our application.
+makeExcerpt('src/index.html', 'import')
:marked
### Displaying the root component
When Angular calls the `bootstrap` function in `main.ts`, it reads the `CliQuickstartAppComponent`
metadata, finds the `cli-quickstart-app` selector, locates an element tag named `cli-quickstart-app`
in the `<body>` tag of the `index.html`, and renders our application's view between those tags.
+makeExcerpt('src/index.html', 'body')
:marked
This is just a taste of Angular develoment. There's much more to learn. Now really is the time to
head over to the [Tour of Heroes Tutorial](./tutorial)!
If you're new to Angular, we recommend staying on the
[learning path](guide/learning-angular.html "Angular learning path").
You can skip the "Setup" chapter since you're already using the Angular-CLI setup.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB