diff --git a/gulpfile.js b/gulpfile.js index e549eae815..2f05977376 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -221,11 +221,19 @@ function findAndRunE2eTests(filter, outputFile) { // fileName; then shut down the example. All protractor output is appended // to the outputFile. function runE2eTsTests(appDir, outputFile) { - // start the app - var appRunSpawnInfo = spawnExt('npm',['run','http-server:e2e', '--', '-s' ], { cwd: appDir }); - var tscRunSpawnInfo = spawnExt('npm',['run','tsc'], { cwd: appDir }); + // spawn tasks to start the app + var appBuildSpawnInfo; + var appRunSpawnInfo; - return runProtractor(tscRunSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile); + if (fs.existsSync(path.join(appDir, 'angular-cli.json'))) { + appBuildSpawnInfo = spawnExt('npm', ['run', 'build:cli'], { cwd: appDir }); + appRunSpawnInfo = spawnExt('npm', ['run', 'http-server:cli', '--', '-s'], { cwd: appDir }); + } else { + appBuildSpawnInfo = spawnExt('npm',['run','tsc'], { cwd: appDir }); + appRunSpawnInfo = spawnExt('npm',['run','http-server:e2e', '--', '-s' ], { cwd: appDir }); + } + + return runProtractor(appBuildSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile); } function runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile) { diff --git a/public/docs/_examples/cli-quickstart/e2e-spec.ts b/public/docs/_examples/cli-quickstart/e2e-spec.ts new file mode 100644 index 0000000000..4134ed74a1 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/e2e-spec.ts @@ -0,0 +1,11 @@ +/// +describe('cli-quickstart App', () => { + beforeEach(() => { + return browser.get('/'); + }) + + it('should display message saying app works', () => { + var pageTitle = element(by.css('cli-quickstart-app h1')).getText() + expect(pageTitle).toEqual('My First Angular 2 App'); + }); +}); diff --git a/public/docs/_examples/cli-quickstart/ts/.gitignore b/public/docs/_examples/cli-quickstart/ts/.gitignore new file mode 100644 index 0000000000..766f37285b --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/.gitignore @@ -0,0 +1,38 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp + +# dependencies +/node_modules +/bower_components + +# IDEs and editors +/.idea + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log +/typings + +# e2e +/e2e/*.js +/e2e/*.map + +#System Files +.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 diff --git a/public/docs/_examples/cli-quickstart/ts/angular-cli-build.js b/public/docs/_examples/cli-quickstart/ts/angular-cli-build.js new file mode 100644 index 0000000000..dad887ff3d --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/angular-cli-build.js @@ -0,0 +1,17 @@ +/* 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', + 'reflect-metadata/**/*.+(js|js.map)', + 'rxjs/**/*.+(js|js.map)', + '@angular/**/*.+(js|js.map)' + ] + }); +}; diff --git a/public/docs/_examples/cli-quickstart/ts/angular-cli.json b/public/docs/_examples/cli-quickstart/ts/angular-cli.json new file mode 100644 index 0000000000..16964f2477 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/angular-cli.json @@ -0,0 +1,31 @@ +{ + "project": { + "version": "1.0.0-beta.5", + "name": "cli-quickstart" + }, + "apps": [ + { + "main": "src/main.ts", + "tsconfig": "src/tsconfig.json", + "mobile": false + } + ], + "addons": [], + "packages": [], + "e2e": { + "protractor": { + "config": "config/protractor.conf.js" + } + }, + "test": { + "karma": { + "config": "config/karma.conf.js" + } + }, + "defaults": { + "prefix": "app", + "sourceDir": "src", + "styleExt": "css", + "prefixInterfaces": false + } +} diff --git a/public/docs/_examples/cli-quickstart/ts/config/environment.dev.ts b/public/docs/_examples/cli-quickstart/ts/config/environment.dev.ts new file mode 100644 index 0000000000..ffe8aed766 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/config/environment.dev.ts @@ -0,0 +1,3 @@ +export const environment = { + production: false +}; diff --git a/public/docs/_examples/cli-quickstart/ts/config/environment.js b/public/docs/_examples/cli-quickstart/ts/config/environment.js new file mode 100644 index 0000000000..4fa28880da --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/config/environment.js @@ -0,0 +1,10 @@ +/* jshint node: true */ + +module.exports = function(environment) { + return { + environment: environment, + baseURL: '/', + locationType: 'auto' + }; +}; + diff --git a/public/docs/_examples/cli-quickstart/ts/config/environment.prod.ts b/public/docs/_examples/cli-quickstart/ts/config/environment.prod.ts new file mode 100644 index 0000000000..3612073bc3 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/config/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; diff --git a/public/docs/_examples/cli-quickstart/ts/config/karma.conf.js b/public/docs/_examples/cli-quickstart/ts/config/karma.conf.js new file mode 100644 index 0000000000..d39036fa52 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/config/karma.conf.js @@ -0,0 +1,42 @@ +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/reflect-metadata/Reflect.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 + }); +}; diff --git a/public/docs/_examples/cli-quickstart/ts/config/protractor.conf.js b/public/docs/_examples/cli-quickstart/ts/config/protractor.conf.js new file mode 100644 index 0000000000..57f4f87dd7 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/config/protractor.conf.js @@ -0,0 +1,29 @@ +/*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()); + } +}; diff --git a/public/docs/_examples/cli-quickstart/ts/e2e/app.e2e.ts b/public/docs/_examples/cli-quickstart/ts/e2e/app.e2e.ts new file mode 100644 index 0000000000..130d236c1c --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/e2e/app.e2e.ts @@ -0,0 +1,14 @@ +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!'); + }); +}); diff --git a/public/docs/_examples/cli-quickstart/ts/e2e/app.po.ts b/public/docs/_examples/cli-quickstart/ts/e2e/app.po.ts new file mode 100644 index 0000000000..645e0e83a8 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/e2e/app.po.ts @@ -0,0 +1,9 @@ +export class CliQuickstartPage { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('cli-quickstart-app h1')).getText(); + } +} diff --git a/public/docs/_examples/cli-quickstart/ts/example-config.json b/public/docs/_examples/cli-quickstart/ts/example-config.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/cli-quickstart/ts/public/.npmignore b/public/docs/_examples/cli-quickstart/ts/public/.npmignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.css b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.css new file mode 100644 index 0000000000..a2b21fae82 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.css @@ -0,0 +1,6 @@ +/* #docregion */ +h1 { + color: #369; + font-family: Arial, Helvetica, sans-serif; + font-size: 250%; +} diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.html b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.html new file mode 100644 index 0000000000..009d49dfa6 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.html @@ -0,0 +1,2 @@ + +

{{title}}

diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.spec.ts b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.spec.ts new file mode 100644 index 0000000000..90abbf1298 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.spec.ts @@ -0,0 +1,22 @@ +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!'); + })); +}); diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.ts b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.ts new file mode 100644 index 0000000000..5510df7476 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/cli-quickstart.component.ts @@ -0,0 +1,17 @@ +// #docregion import +import { Component } from '@angular/core'; +// #enddocregion import + +// #docregion metadata +@Component({ + moduleId: module.id, + selector: 'cli-quickstart-app', + templateUrl: 'cli-quickstart.component.html', + styleUrls: ['cli-quickstart.component.css'] +}) +// #enddocregion metadata +// #docregion title, class +export class CliQuickstartAppComponent { + title = 'My First Angular 2 App'; +} +// #enddocregion title, class diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/environment.ts b/public/docs/_examples/cli-quickstart/ts/src/app/environment.ts new file mode 100644 index 0000000000..79ee96fdfd --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/environment.ts @@ -0,0 +1,7 @@ +// 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 +}; diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/index.ts b/public/docs/_examples/cli-quickstart/ts/src/app/index.ts new file mode 100644 index 0000000000..e4a0d09c55 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/app/index.ts @@ -0,0 +1,2 @@ +export * from './environment'; +export * from './cli-quickstart.component'; diff --git a/public/docs/_examples/cli-quickstart/ts/src/app/shared/index.ts b/public/docs/_examples/cli-quickstart/ts/src/app/shared/index.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/public/docs/_examples/cli-quickstart/ts/src/favicon.ico b/public/docs/_examples/cli-quickstart/ts/src/favicon.ico new file mode 100644 index 0000000000..8081c7ceaf Binary files /dev/null and b/public/docs/_examples/cli-quickstart/ts/src/favicon.ico differ diff --git a/public/docs/_examples/cli-quickstart/ts/src/index.html b/public/docs/_examples/cli-quickstart/ts/src/index.html new file mode 100644 index 0000000000..d0efe67fee --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/index.html @@ -0,0 +1,35 @@ + + + + + + CliQuickstart + + + {{#unless environment.production}} + + {{/unless}} + + + + + + Loading... + + + + {{#each scripts.polyfills}}{{/each}} + + + + + + + + + + diff --git a/public/docs/_examples/cli-quickstart/ts/src/main.ts b/public/docs/_examples/cli-quickstart/ts/src/main.ts new file mode 100644 index 0000000000..c3561a2c57 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/main.ts @@ -0,0 +1,18 @@ +// #docplaster +// #docregion important +import { bootstrap } from '@angular/platform-browser-dynamic'; + +// #enddocregion important +import { enableProdMode } from '@angular/core'; +import { environment } from './app/'; +// #docregion important +import { CliQuickstartAppComponent } from './app/'; +// #enddocregion important +if (environment.production) { + enableProdMode(); +} + +// #docregion important + +bootstrap(CliQuickstartAppComponent); +// #enddocregion important diff --git a/public/docs/_examples/cli-quickstart/ts/src/system-config.ts b/public/docs/_examples/cli-quickstart/ts/src/system-config.ts new file mode 100644 index 0000000000..d2af1aac0c --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/system-config.ts @@ -0,0 +1,54 @@ +/*********************************************************************************************** + * 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 }); diff --git a/public/docs/_examples/cli-quickstart/ts/src/typings.d.ts b/public/docs/_examples/cli-quickstart/ts/src/typings.d.ts new file mode 100644 index 0000000000..eebc2728b8 --- /dev/null +++ b/public/docs/_examples/cli-quickstart/ts/src/typings.d.ts @@ -0,0 +1 @@ +/// diff --git a/public/docs/_examples/package.json b/public/docs/_examples/package.json index e783edfb73..f72f1f53e8 100644 --- a/public/docs/_examples/package.json +++ b/public/docs/_examples/package.json @@ -7,6 +7,7 @@ "e2e": "tsc && concurrently \"http-server\" \"protractor protractor.config.js\"", "http-server": "tsc && http-server", "http-server:e2e": "http-server", + "http-server:cli": "http-server dist/", "lite": "lite-server", "postinstall": "typings install", "test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"", @@ -17,7 +18,8 @@ "webdriver:update": "webdriver-manager update", "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 --progress --profile --bail" + "build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail", + "build:cli": "ng build" }, "keywords": [], "author": "", @@ -32,17 +34,16 @@ "@angular/router": "2.0.0-rc.1", "@angular/router-deprecated": "2.0.0-rc.1", "@angular/upgrade": "2.0.0-rc.1", - "systemjs": "0.19.27", "core-js": "^2.4.0", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.6", "zone.js": "^0.6.12", - "angular2-in-memory-web-api": "0.0.11", "bootstrap": "^3.3.6" }, "devDependencies": { + "angular-cli": "^1.0.0-beta.5", "canonical-path": "0.0.2", "concurrently": "^2.0.0", "css-loader": "^0.23.1", diff --git a/public/docs/ts/latest/_data.json b/public/docs/ts/latest/_data.json index de9647567c..ac205db03d 100644 --- a/public/docs/ts/latest/_data.json +++ b/public/docs/ts/latest/_data.json @@ -6,6 +6,13 @@ "banner": "欢迎来到 Angular in TypeScript! 当前的Angular版本是 rc.1。请参考变更记录。" }, + "cli-quickstart": { + "icon": "query-builder", + "title": "CLI Quickstart", + "description": "Use the CLI tool to build apps quickly in Angular 2", + "hide": true + }, + "quickstart": { "icon": "query-builder", "title": "五分钟“快速起步”", diff --git a/public/docs/ts/latest/cli-quickstart.jade b/public/docs/ts/latest/cli-quickstart.jade new file mode 100644 index 0000000000..0a9a2d8636 --- /dev/null +++ b/public/docs/ts/latest/cli-quickstart.jade @@ -0,0 +1,278 @@ +include _util-fns + +:marked + Good tools make application development quicker and easier to maintain than + if we 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 + as testing, bundling, and deployment. + + Our goal in this CLI QuickStart chapter is to build and run a super-simple Angular 2 + application in TypeScript, using Angular-CLI + while adhering to the [Style Guide](./guide/style-guide.html) recommendations that + benefit _every_ Angular 2 project. + + By the end of the chapter, we'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: + + 1. [Set up](#devenv) the development environment + 2. [Create](#create-proj) a new project and skeleton application + 3. [Serve](#serve) the application + 4. [Edit](#first-component) the application + + +.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. + + 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 `v5.x.x` and npm `3.x.x`** + by running `node -v` and `npm -v` in a terminal/console window. + Older versions produce errors. +:marked + Then **install the [Angular-CLI](https://github.com/angular/angular-cli)** globally. + +code-example(format=""). + 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 symbolic links + 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 + +.l-sub-section + :marked + Patience please. + It takes time to set up a new project, most of it spent installing npm packages. + +.l-main-section +h2#serve Step 3: Serve the application +:marked + Go to the project directory and launch the server. +code-example(format=""). + cd cli-quickstart + ng serve +:marked + The `ng serve` command launches the server, watches our files, + and rebuilds the app as we make changes to the files. + + Open a browser on `http://localhost:4200/`; the app greets us with a message: + +figure.image-display + img(src='/resources/images/devguide/cli-quickstart/app-works.png' alt="Our app works!") + +.l-main-section +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. + +:marked + Open the component file and change the `title` property from _cli-quickstart works!_ to _My First Angular 2 App_: + ++makeExample('cli-quickstart/ts/src/app/cli-quickstart.component.ts', 'title', 'src/app/cli-quickstart.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=".") + +figure.image-display + img(src='/resources/images/devguide/cli-quickstart/my-first-app.png' alt="Output of QuickStart app") + +:marked + Looking good! + +.l-main-section +:marked + ## What's next? + Our first application doesn't do much. It's basically "Hello, World" for Angular 2. + + We kept it simple in our first pass: we wrote our first Angular 2 application using the angular CLI + and modified our first component. That's about all we'd expect to do for a "Hello, World" app. + + **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 2. + + 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. +

+.l-main-section +h1#behind-the-code Behind the code +:marked + ### CliQuickstartAppComponent is the root of the application + + 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 — a *view* — through its associated template. + + This QuickStart has only one, extremely simple component. + But it has the essential structure of every component we'll ever write: + + * 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. + +a#component-import +:marked + ### Import + + Angular apps are modular. They consist of many files, each dedicated to a purpose. + + Angular itself is modular. It is a collection of library modules + consisting of several, related features that we'll use to build our application. + + When we need something from a module or library, we import it. + Here we import the `Component` decorator from the Angular 2 **_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') + +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. + + 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. + ++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 `` 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 `

` 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 _My First Angular 2 App_. + 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 `` 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 2 develoment. There's much more to learn. Now really is the time to + head over to the [Tour of Heroes Tutorial](./tutorial)! diff --git a/public/resources/images/devguide/cli-quickstart/app-works.png b/public/resources/images/devguide/cli-quickstart/app-works.png new file mode 100644 index 0000000000..e0b9fb73f5 Binary files /dev/null and b/public/resources/images/devguide/cli-quickstart/app-works.png differ diff --git a/public/resources/images/devguide/cli-quickstart/my-first-app.png b/public/resources/images/devguide/cli-quickstart/my-first-app.png new file mode 100644 index 0000000000..77a660ad77 Binary files /dev/null and b/public/resources/images/devguide/cli-quickstart/my-first-app.png differ