parent
f3205f5beb
commit
fb49cbe33f
16
gulpfile.js
16
gulpfile.js
|
@ -221,11 +221,19 @@ function findAndRunE2eTests(filter, outputFile) {
|
||||||
// fileName; then shut down the example. All protractor output is appended
|
// fileName; then shut down the example. All protractor output is appended
|
||||||
// to the outputFile.
|
// to the outputFile.
|
||||||
function runE2eTsTests(appDir, outputFile) {
|
function runE2eTsTests(appDir, outputFile) {
|
||||||
// start the app
|
// spawn tasks to start the app
|
||||||
var appRunSpawnInfo = spawnExt('npm',['run','http-server:e2e', '--', '-s' ], { cwd: appDir });
|
var appBuildSpawnInfo;
|
||||||
var tscRunSpawnInfo = spawnExt('npm',['run','tsc'], { cwd: appDir });
|
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) {
|
function runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile) {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/// <reference path="../_protractor/e2e.d.ts" />
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
|
@ -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
|
|
@ -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)'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const environment = {
|
||||||
|
production: false
|
||||||
|
};
|
|
@ -0,0 +1,10 @@
|
||||||
|
/* jshint node: true */
|
||||||
|
|
||||||
|
module.exports = function(environment) {
|
||||||
|
return {
|
||||||
|
environment: environment,
|
||||||
|
baseURL: '/',
|
||||||
|
locationType: 'auto'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const environment = {
|
||||||
|
production: true
|
||||||
|
};
|
|
@ -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
|
||||||
|
});
|
||||||
|
};
|
|
@ -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());
|
||||||
|
}
|
||||||
|
};
|
|
@ -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!');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
export class CliQuickstartPage {
|
||||||
|
navigateTo() {
|
||||||
|
return browser.get('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
getParagraphText() {
|
||||||
|
return element(by.css('cli-quickstart-app h1')).getText();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
/* #docregion */
|
||||||
|
h1 {
|
||||||
|
color: #369;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 250%;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
<!-- #docregion -->
|
||||||
|
<h1>{{title}}</h1>
|
|
@ -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!');
|
||||||
|
}));
|
||||||
|
});
|
|
@ -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
|
|
@ -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
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './environment';
|
||||||
|
export * from './cli-quickstart.component';
|
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
|
@ -0,0 +1,35 @@
|
||||||
|
<!-- #docplaster -->
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CliQuickstart</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 -->
|
||||||
|
</body>
|
||||||
|
<!-- #enddocregion body -->
|
||||||
|
</html>
|
|
@ -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
|
|
@ -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 });
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference path="../typings/index.d.ts" />
|
|
@ -7,6 +7,7 @@
|
||||||
"e2e": "tsc && concurrently \"http-server\" \"protractor protractor.config.js\"",
|
"e2e": "tsc && concurrently \"http-server\" \"protractor protractor.config.js\"",
|
||||||
"http-server": "tsc && http-server",
|
"http-server": "tsc && http-server",
|
||||||
"http-server:e2e": "http-server",
|
"http-server:e2e": "http-server",
|
||||||
|
"http-server:cli": "http-server dist/",
|
||||||
"lite": "lite-server",
|
"lite": "lite-server",
|
||||||
"postinstall": "typings install",
|
"postinstall": "typings install",
|
||||||
"test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
|
"test": "tsc && concurrently \"tsc -w\" \"karma start karma.conf.js\"",
|
||||||
|
@ -17,7 +18,8 @@
|
||||||
"webdriver:update": "webdriver-manager update",
|
"webdriver:update": "webdriver-manager update",
|
||||||
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
|
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
|
||||||
"test:webpack": "karma start karma.webpack.conf.js",
|
"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": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
|
@ -32,17 +34,16 @@
|
||||||
"@angular/router": "2.0.0-rc.1",
|
"@angular/router": "2.0.0-rc.1",
|
||||||
"@angular/router-deprecated": "2.0.0-rc.1",
|
"@angular/router-deprecated": "2.0.0-rc.1",
|
||||||
"@angular/upgrade": "2.0.0-rc.1",
|
"@angular/upgrade": "2.0.0-rc.1",
|
||||||
|
|
||||||
"systemjs": "0.19.27",
|
"systemjs": "0.19.27",
|
||||||
"core-js": "^2.4.0",
|
"core-js": "^2.4.0",
|
||||||
"reflect-metadata": "^0.1.3",
|
"reflect-metadata": "^0.1.3",
|
||||||
"rxjs": "5.0.0-beta.6",
|
"rxjs": "5.0.0-beta.6",
|
||||||
"zone.js": "^0.6.12",
|
"zone.js": "^0.6.12",
|
||||||
|
|
||||||
"angular2-in-memory-web-api": "0.0.11",
|
"angular2-in-memory-web-api": "0.0.11",
|
||||||
"bootstrap": "^3.3.6"
|
"bootstrap": "^3.3.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"angular-cli": "^1.0.0-beta.5",
|
||||||
"canonical-path": "0.0.2",
|
"canonical-path": "0.0.2",
|
||||||
"concurrently": "^2.0.0",
|
"concurrently": "^2.0.0",
|
||||||
"css-loader": "^0.23.1",
|
"css-loader": "^0.23.1",
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
"banner": "Welcome to <b>Angular in TypeScript</b>! The current Angular 2 release is <b>rc.1</b>. Please consult the <a href='https://github.com/angular/angular/blob/master/CHANGELOG.md' target='_blank'> Change Log</a> about recent enhancements, fixes, and breaking changes."
|
"banner": "Welcome to <b>Angular in TypeScript</b>! The current Angular 2 release is <b>rc.1</b>. Please consult the <a href='https://github.com/angular/angular/blob/master/CHANGELOG.md' target='_blank'> Change Log</a> about recent enhancements, fixes, and breaking changes."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"cli-quickstart": {
|
||||||
|
"icon": "query-builder",
|
||||||
|
"title": "CLI Quickstart",
|
||||||
|
"description": "Use the CLI tool to build apps quickly in Angular 2",
|
||||||
|
"hide": true
|
||||||
|
},
|
||||||
|
|
||||||
"quickstart": {
|
"quickstart": {
|
||||||
"icon": "query-builder",
|
"icon": "query-builder",
|
||||||
"title": "5 Min Quickstart",
|
"title": "5 Min Quickstart",
|
||||||
|
|
|
@ -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 <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
|
||||||
|
|
||||||
|
.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.
|
||||||
|
<br><br>
|
||||||
|
.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 `<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 _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 `<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 2 develoment. There's much more to learn. Now really is the time to
|
||||||
|
head over to the [Tour of Heroes Tutorial](./tutorial)!
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Loading…
Reference in New Issue