forked from angular/angular.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquickstart.jade
568 lines (456 loc) · 22.2 KB
/
quickstart.jade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
block includes
include _util-fns
- var _Install = 'Install'
- var _prereq = 'Node.js'
- var _angular_browser_uri = '@angular/platform-browser-dynamic'
- var _angular_core_uri = '@angular/core'
- var _appDir = 'app'
- var _indexHtmlDir = 'project root'
:marked
Our QuickStart goal is to build and run a super-simple
Angular 2 application in #{_Lang}, and
establish a development environment for the remaining documentation samples
that also can be the foundation for real world applications.
.callout.is-helpful
header Don't want #{_Lang}?
p.
Although we're getting started in #{_Lang}, you can also write Angular 2 apps
in #{_docsFor == 'ts' ? 'Dart' : 'TypeScript'} and JavaScript.
Just select either of those languages from the combo-box in the banner.
h1 Try it!
p
| Try the #[+liveExampleLink2('live example', 'quickstart')] which loads the sample app
+ifDocsFor('ts')
| in #[a(href="http://plnkr.co/" title="Plunker" target="_blank") plunker]
| and displays the simple message:
figure.image-display
img(src='/resources/images/devguide/quickstart/my-first-app.png' alt="Output of QuickStart app")
h1 Build this app!
:marked
- [Prerequisite](#prereq): Install #{_prereq}
- [Step 1](#create-and-configure): Create the app’s project folder and
define package dependencies and special project setup
- [Step 2](#root-component): Create the app’s Angular root component
- [Step 3](#main): Add `main.#{_docsFor}`, identifying the root component to Angular
- [Step 4](#index): Add `index.html`, the web page that hosts the application
- [Step 5](#build-and-run): Build and run the app
- [Make some changes to the app](#make-some-changes)
- [Wrap up](#wrap-up)
.l-main-section
h2#prereq Prerequisite: #{_prereq}
block setup-tooling
:marked
Install **[Node.js® and npm](https://nodejs.org/en/download/)**
if they are not already on your machine.
block download-source
.l-main-section
.callout.is-helpful
header Download the source
:marked
Instead of following each step of these instructions, we can
[download the QuickStart source](https://github.com/angular/quickstart/blob/master/README.md)
from github and follow its brief instructions.
.l-main-section
button(class="verbose off md-primary md-button md-ink-ripple", type="button", onclick="verbose(false)").
Hide explanations
button(class="verbose on md-primary md-button md-ink-ripple", type="button", onclick="verbose(true)").
View explanations
.l-verbose-section
:marked
*Explanations* describe the concepts and reasons behind the instructions.
Explanations have a thin border on the left like *this* block of text.
Click *Hide Explanations* to show only the instructions.
Click *View Explanations* to see everything again.
.l-sub-section
:marked
We'll see many code blocks as we build the QuickStart app. They're all easy to copy and paste:
code-example(format="nocode").
Click the glyph on the right to copy code snippets to the clipboard ==>
.l-main-section
h2#create-and-configure Step 1: Create and configure the project
- var _package_and_config_files = _docsFor == 'dart' ? 'pubspec.yaml' : 'package definition and configuration files'
:marked
In this step we:
* [(a) Create the project folder](#create-the-project-folder)
* [(b) Add #{_package_and_config_files}](#add-config-files)
* [(c) #{_Install} packages](#install-packages)
h3 (a) Create the project folder
code-example(language="sh").
mkdir angular2-quickstart
cd angular2-quickstart
h3#add-config-files (b) Add #{_package_and_config_files}
block package-and-config-files
- var _tsconfigUri = 'guide/typescript-configuration.html#tsconfig'
- var _typingsUri = 'guide/typescript-configuration.html#!#typings'
p Add the following package definition and configuration files to the project folder:
ul
li.
#[b package.json] lists packages the QuickStart app depends on and
defines some useful scripts.
See #[a(href="guide/npm-packages.html") Npm Package Configuration] for details.
li.
#[b tsconfig.json] is the TypeScript compiler configuration file.
See #[a(href="#{_tsconfigUri}") TypeScript Configuration] for details.
li.
#[b typings.json] identifies TypeScript definition files.
See #[a(href="#{_typingsUri}") TypeScript Configuration] for details.
li.
#[b systemjs.config.js], the SystemJS configuration file.
See discussion #[a(href="#systemjs") below].
a#config-files
+makeTabs(`
quickstart/ts/package.1.json,
quickstart/ts/tsconfig.1.json,
quickstart/ts/typings.1.json,
quickstart/ts/systemjs.config.1.js
`, '', `
package.json,
tsconfig.json,
typings.json,
systemjs.config.js
`)
h3#install-packages (c) #{_Install} packages
block install-packages
:marked
We install the packages listed in `package.json` using `npm`. Enter the
following command in a terminal window (command window in Windows):
code-example(language="sh").
npm install
.alert.is-important
:marked
Scary <span style="color:red; font-weight: bold">error messages in red</span> may appear **during** install.
The install typically recovers from these errors and finishes successfully.
.l-verbose-section(class="l-verbose-inherit")
:marked
#### npm errors and warnings
All is well if there are no console messages starting with `npm ERR!` *at the end* of **npm install**.
There might be a few `npm WARN` messages along the way — and that is perfectly fine.
We often see an `npm WARN` message after a series of `gyp ERR!` messages.
Ignore them. A package may try to recompile itself using `node-gyp`.
If the recompile fails, the package recovers (typically with a pre-built version)
and everything works.
Just make sure there are no `npm ERR!` messages at the end of `npm install`.
.l-verbose-section
:marked
#### Adding the libraries and packages we need with *npm*
Angular application developers rely on the _[npm](https://docs.npmjs.com)_
package manager to install the libraries and packages their apps require.
The Angular team recommends the starter-set of packages specified in the
`dependencies` and `devDependencies` sections.
See the [npm packages](guide/npm-packages.html) chapter for details.
#### Helpful scripts
We've included a number of npm scripts in our suggested `package.json` to handle common development tasks:
+makeJson('quickstart/ts/package.1.json',{ paths: 'scripts'}, 'package.json (scripts)')(format=".")
:marked
We execute most npm scripts in the following way: `npm run` followed by a *script-name*.
Some commands (such as `start`) don't require the `run` keyword.
Here's what these scripts do:
* `npm start` - runs the compiler and a server at the same time, both in "watch mode"
* `npm run tsc` - runs the TypeScript compiler once
* `npm run tsc:w` - runs the TypeScript compiler in watch mode;
the process keeps running, awaiting changes to TypeScript files and recompiling when it sees them
* `npm run lite` - runs the <a href="https://www.npmjs.com/package/lite-server" target="_blank">lite-server</a>,
a light-weight, static file server with excellent support for Angular apps that use routing
* `npm run typings` - runs the [*typings* tool](#{_typingsUri}) separately
* `npm run postinstall` - called by *npm* automatically *after* it successfully completes package installation.
This script installs the [TypeScript definition files](#{_typingsUri}) defined in `typings.json`
:marked
**We're all set.** Let's write some code.
.l-main-section
h2#root-component Step 2: Our first Angular component
:marked
Let's create a folder to hold our application and add a super-simple Angular component.
**Create #{_an} #{_appDir} subfolder** off the project root directory:
code-example.
mkdir #{_appDir}
a#app-component
p.
#[b Create the component file]
#[code #[+adjExPath('app/app.component.ts')]] (in this newly created directory) with the following content:
+makeProjExample('app/app.component.ts')
.l-verbose-section
:marked
### AppComponent is the root of the application
Every Angular app has at least one **root component**, conventionally named `AppComponent`,
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
each made up 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 Angular 2 core so that our component code can have access to
the `@Component` #{_decorator}.
+makeExcerpt('app/app.component.ts', 'import')
h3#component-decorator @Component #{_decorator}
+ifDocsFor('ts')
:marked
`Component` is a *decorator function* that takes a *metadata object* as argument.
We apply this function to the component class by prefixing the function with the
**@** symbol and invoking it with a metadata object, just above the class.
:marked
`@Component` is #{_a} *#{_decorator}* that allows us to associate *metadata* with the
component class.
The metadata tells Angular how to create and use this component.
+makeExcerpt('app/app.component.ts', 'metadata')
block annotation-fields
:marked
This particular metadata object has two fields, a `selector` and a `template`.
:marked
The **selector** specifies a simple CSS selector for an HTML element that represents the component.
>The element for this component is named `my-app`.
Angular creates and displays an instance of our `AppComponent`
wherever it encounters a `my-app` element in the host HTML.
The **template** specifies the component's companion template,
written in an enhanced form of HTML that tells Angular how to render this component's view.
>Our template is a single line of HTML announcing "*My First Angular 2 App*".
>A more advanced template could contain data bindings to component properties
and might identify other application components which have their own templates.
These templates might identify yet other components.
In this way an Angular application becomes a tree of components.
:marked
### Component class
At the bottom of the file is an empty, do-nothing class named `AppComponent`.
+makeExcerpt('app/app.component.ts', 'class')
:marked
When we're ready to build a substantive application,
we can expand this class with properties and application logic.
Our `AppComponent` class is empty because we don't need it to do anything in this QuickStart.
+ifDocsFor('ts')
:marked
We **export** `AppComponent` so that we can **import** it elsewhere in our application,
as we'll see when we create `main.ts`.
.l-main-section
h2#main Step 3: Add #[code #[+adjExPath('main.ts')]]
block create-main
p.
Now we need something to tell Angular to load the root component.
Create the file #[code #[+adjExPath('app/main.ts')]] with the following content:
+makeProjExample('app/main.ts')
.l-verbose-section
:marked
We import the two things we need to launch the application:
1. Angular's browser `bootstrap` function
1. The application root component, `AppComponent`.
Then we call `bootstrap` with `AppComponent`.
### Bootstrapping is platform-specific
Notice that we import the `bootstrap` function from `#{_angular_browser_uri}`,
not `#{_angular_core_uri}`.
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 separate *main.#{_docsFor}* and app component files?
Both `main.#{_docsFor}` and the app 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 `AppComponent` 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*.
.l-main-section
h2#index Step 4: Add #[code index.html]
:marked
In the *#{_indexHtmlDir}* folder
create an `index.html` file and paste the following lines into it:
+makeProjExample('index.html')
.l-verbose-section
:marked
The `index.html` file defines the web page that hosts the application.
block index-html-commentary-for-ts
:marked
The noteworthy sections of HTML are:
1. The JavaScript [libraries](#libraries)
2. Configuration file for [SystemJS](#systemjs), and a script
where we import and run the `app` module which refers to the `main` file that we just wrote.
3. The [`<my-app>`](#my-app) tag in the `<body>` which is *where our app lives!*
:marked
### Libraries
We loaded the following scripts
+makeExcerpt('index.html', 'libraries')
:marked
We begin with es6-shim which monkey patches the global context (window) with essential features of ES2015 (ES6).
Next are the polyfills for Angular2, `zone.js` and `reflect-metadata`.
Then the [SystemJS](#systemjs) library for module loading.
We'll make different choices as we gain experience and
become more concerned about production qualities such as
load times and memory footprint.
h3#systemjs SystemJS
:marked
QuickStart uses <a href="https://github.com/systemjs/systemjs" target="_blank">SystemJS</a>
to load application and library modules. [Earlier](#add-config-files) we
added the `systemjs.config.js` file to the project root.
There are alternatives that work just fine including the well-regarded
[webpack](guide/webpack.html).
SystemJS happens to be a good choice.
But we want to be clear that it was a *choice* and not a *preference*.
All module loaders require configuration and all loader configuration
becomes complicated rather quickly as soon as the file structure diversifies and
we start thinking about building for production and performance.
We suggest becoming well-versed in the loader of your choice.
Learn more about SystemJS configuration
<a href="https://github.com/systemjs/systemjs/blob/master/docs/config-api.md" target="_blank">here</a>.
With those cautions in mind, what are we doing in the
QuickStart [`systemjs.config.js` configuration file we added earlier](#config-files)?
First, we create a map to tell SystemJS where to look when we import some module.
Then, we register all our packages to SystemJS:
all the project dependencies and our application package, `app`.
.l-sub-section
:marked
Our QuickStart doesn't use all of the listed packages
but any substantial application will want many of them
and all of the listed packages are required by at least one of the documentation samples.
There is no runtime harm in listing packages that we don't need as they will only be loaded when requested.
:marked
The `app` package tells SystemJS what to do when it sees a request for a
module from the `app/` folder.
Our QuickStart makes such requests when one of its
application TypeScript files has an import statement like this:
+makeExcerpt('app/main.ts', 'import')
:marked
Notice that the module name (after `from`) does not mention a filename extension.
In the configuration we tell SystemJS to default the extension to `js`, a JavaScript file.
That makes sense because we transpile TypeScript to JavaScript
*before* running the application.
.l-sub-section
:marked
#### Transpiling in the browser
In the live example on plunker we transpile (AKA compile) to JavaScript in the browser
on the fly. _That's fine for a demo_.
**Do not transpile in the browser during development or for production**.
We strongly recommend transpiling (AKA compiling) to JavaScript during a build phase
before running the application for several reasons including:
* We see compiler warnings and errors that are hidden from us in the browser.
* Precompilation simpifies the module loading process and
it's much easier to diagnose problems when this is a separate, external step.
* Precompilation means a faster user experience because the browser doesn't waste time compiling.
* We iterate development faster because we only recompile changed files.
We notice the difference as soon as the app grows beyond a handful of files.
* Precompilation fits into a continuous integration process of build, test, deploy.
:marked
The `System.import` call tells SystemJS to import the `main` file
(`main.js` ... after transpiling `main.ts`, remember?);
`main` is where we tell Angular to launch the application.
We also catch and log launch errors to the console.
All other modules are loaded upon request
either by an import statement or by Angular itself.
### *<my-app>*
a(id="my-app")
:marked
When Angular calls the `bootstrap` function in `main.#{_docsFor}`, it reads the `AppComponent`
metadata, finds the `my-app` selector, locates an element tag named `my-app`,
and renders our application's view between those tags.
:marked
### Add some style
Styles aren't essential but they're nice, and `index.html` assumes we have
a stylesheet called `styles.css`.
Create a `styles.css` file in the *#{_indexHtmlDir}* folder and start styling, perhaps with the minimal
styles shown below. For the full set of master styles used by the documentation samples,
see [styles.css](https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css).
+makeExcerpt('styles.1.css')
.l-main-section
h2#build-and-run Step 5: Build and run the app!
block run-app
:marked
Open a terminal window and enter this command:
code-example.
npm start
:marked
That command runs two parallel node processes
1. The TypeScript compiler in watch mode
1. A static server called **lite-server** that loads `index.html` in a browser
and refreshes the browser when application files change
In a few moments, a browser tab should open and display
figure.image-display
img(src='/resources/images/devguide/quickstart/my-first-app.png' alt="Output of QuickStart app")
:marked
**Great job!**
block build-app
//- Nothing for ts.
:marked
## Make some changes
Try changing the message to "My SECOND Angular 2 app".
block server-watching
:marked
The TypeScript compiler and `lite-server` are watching.
They should detect the change, recompile the TypeScript into JavaScript,
refresh the browser, and display the revised message.
It's a nifty way to develop an application!
We close the terminal window when we're done to terminate both the compiler and the server.
.l-main-section
:marked
# Wrap up
Our final project folder structure looks like this:
block project-file-structure
.filetree
.file angular2-quickstart
.children
.file app
.children
.file app.component.ts
.file main.ts
.file node_modules ...
.file typings ...
.file index.html
.file package.json
.file styles.css
.file systemjs.config.js
.file tsconfig.json
.file typings.json
:marked
Here are the file contents:
block project-files
+makeTabs(`
quickstart/ts/app/app.component.ts,
quickstart/ts/app/main.ts,
quickstart/ts/index.html,
quickstart/ts/package.1.json,
quickstart/ts/tsconfig.1.json,
quickstart/ts/typings.1.json,
quickstart/ts/styles.1.css,
quickstart/ts/systemjs.config.1.js`
,null,
`app/app.component.ts,
app/main.ts,
index.html,
package.json,
tsconfig.json,
typings.json,
styles.css,
systemjs.config.js`)
.l-main-section
:marked
## What 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 a little Angular component,
created a simple `index.html`, and launched with a
static file server. That's about all we'd expect to do for a "Hello, World" app.
**We have greater ambitions!**
block what-next-ts-overhead
:marked
The good news is that the overhead of setup is (mostly) behind us.
We'll probably only touch the `package.json` to update libraries.
We'll likely open `index.html` only if we need to add a library or some css stylesheets.
: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)!