369 lines
12 KiB
Plaintext
369 lines
12 KiB
Plaintext
include ../../../../_includes/_util-fns
|
|
|
|
:markdown
|
|
Let's start from zero and build a simple Angular 2 application in TypeScript.
|
|
|
|
.callout.is-helpful
|
|
header Don't want TypeScript?
|
|
:markdown
|
|
Although we're getting started in TypeScript, you can also write Angular 2 apps
|
|
in JavaScript and Dart by selecting either of those languages from the combo-box in the banner.
|
|
|
|
:markdown
|
|
We'll do it in short steps
|
|
1. Install the prerequisites for Angular TypeScript development
|
|
1. Create the application project structure
|
|
1. Install the npm packages our app needs
|
|
1. Prepare for TypeScript compilation
|
|
1. Create an **`index.html`**
|
|
1. Write the root component for our application in **`app.ts`**
|
|
1. Bootstrap the app
|
|
1. Compile the TypeScript to JavaScript
|
|
1. Run it
|
|
|
|
.l-main-section
|
|
|
|
:markdown
|
|
## Prerequisites
|
|
|
|
We'll need a base of tools for all of our application development. We'll only install these once starting with
|
|
[**node** and **npm**](https://docs.npmjs.com/getting-started/installing-node "Installing Node.js and updating npm").
|
|
|
|
Now use npm in a terminal (or Windows/Linux command line) to install the **TypeScript compiler** globally
|
|
|
|
pre.prettyprint.lang-bash
|
|
code npm install -g typescript
|
|
|
|
:markdown
|
|
Use npm again to install the [**tsd package manager**](https://www.npmjs.com/package/tsd "TSD Package Manager")
|
|
so we can download TypeScript type definitions files ("`.d.ts`" files)
|
|
from the [DefinitelyTyped](http://definitelytyped.org/) repository.
|
|
|
|
pre.prettyprint.lang-bash
|
|
code npm install -g tsd
|
|
|
|
:markdown
|
|
Install a node **static server** to serve our application.
|
|
We'll use **live-server** for this example because it performs a live reload by default and it's
|
|
fun to watch the browser update as we make changes.
|
|
|
|
pre.prettyprint.lang-bash
|
|
code npm install -g live-server
|
|
|
|
.l-sub-section
|
|
:markdown
|
|
Our success depends upon installing compatible versions of these tools.
|
|
Confirm your version numbers in a terminal window with these commands:
|
|
table
|
|
tr
|
|
th Command
|
|
th Versions
|
|
tr
|
|
td
|
|
code node -v
|
|
td 0.10.* - 0.12.*   But not 4.0.0 !!!
|
|
tr
|
|
td
|
|
code npm -v
|
|
td 2.11+ (3.* is fine)
|
|
tr
|
|
td
|
|
code tsc -v
|
|
td 1.6+
|
|
tr
|
|
td
|
|
code tsd --version
|
|
td 0.6.5+
|
|
tr
|
|
td
|
|
code live-server -v
|
|
td 0.8+
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Create the application project structure
|
|
|
|
Create a new folder to hold our application project, perhaps like this:
|
|
```
|
|
mkdir angular2-getting-started
|
|
cd angular2-getting-started
|
|
```
|
|
|
|
:markdown
|
|
We'll refer to this as our application's **root folder**.
|
|
|
|
Now add a sub-folder - `src` - to hold project source code and a sub-sub-folder - `src/app` -
|
|
to hold to hold the application source code.
|
|
|
|
In OS/X and Linux:
|
|
|
|
pre.prettyprint.lang-bash
|
|
code mkdir src/app
|
|
|
|
:markdown
|
|
In Windows:
|
|
|
|
pre.prettyprint.lang-bash
|
|
code mkdir src\app
|
|
|
|
:markdown
|
|
Our project folders should look like this.
|
|
```
|
|
angular2-getting-started
|
|
├── src
|
|
└──── app
|
|
|
|
```
|
|
.l-main-section
|
|
:markdown
|
|
## Install npm packages
|
|
|
|
Our application will need some 3rd party JavaScript files:
|
|
|
|
>***angular.js***, the Angular 2 library.
|
|
|
|
>***system.js***, a third-party open-source library that adds module loading functionality to our browser.
|
|
|
|
>***traceur-runtime.js*** to transpile the TypeScript-generated JavaScript into the version of Javascript
|
|
our browser understands (the version known as "ES5").
|
|
|
|
We'll install these package with `npm` and create an npm **`package.json`** configuration file
|
|
that to maintain future packages as our application evolves.
|
|
|
|
In a terminal window, go to the **root** folder and type:
|
|
```
|
|
npm init -y
|
|
npm install --save angular2@2.0.0-alpha.37 systemjs@0.19.2
|
|
```
|
|
|
|
`npm` produced a `node_modules` folder that holds these packages and other packages that *they* require.
|
|
|
|
The essence of our `package.json` should look like this:
|
|
+makeJson('gettingstarted/ts/package.json', { paths: 'name, version, dependencies '})
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Prepare for TypeScript Compilation
|
|
|
|
### Add links to TypeScript definition files
|
|
|
|
We prefer writing TypeScript apps in editors that understand TypeScript,
|
|
such as [Visual Studio Code](https://code.visualstudio.com/) and
|
|
[Web Storm](https://www.jetbrains.com/webstorm/features/).
|
|
|
|
Such editors improve the development experience by checking type information and
|
|
displaying API documentation ("intellisense") based on TypeScript definition files (`.d.ts`).
|
|
|
|
The definition files we need are included in the npm packages we just installed.
|
|
We'll use the
|
|
[**tsd package manager**](https://www.npmjs.com/package/tsd "TSD Package Manager")
|
|
to generate an *aggregate TypeScript definition file*, **`tsd.d.ts`**,
|
|
that holds links to the type definition files in those packages.
|
|
|
|
In the ***root* folder** enter the following command
|
|
|
|
pre.prettyprint.lang-bash
|
|
code tsd link --config src/tsd.json
|
|
|
|
:markdown
|
|
That produces a new **`src/typings`** folder with the **`tsd.d.ts`** file.
|
|
|
|
Now Angular type checking and intellisense lights up automatically as we write our app
|
|
in the Visual Studio Code and Web Storm editors. Check your editor's documentation for
|
|
instructions on using the `tsd.d.ts` file.
|
|
|
|
### Add the TypeScript configuration file
|
|
|
|
We need to tell that editor how to interpret our TypeScript
|
|
which we do with a configuration file named **`tsconfig.json`**.
|
|
This configuration file also simplifies the TypeScript compilation command
|
|
that we'll run very soon.
|
|
|
|
**Change to the `src` folder and create a `tsconfig.json`** file with the following content:
|
|
+makeJson('gettingstarted/ts/src/tsconfig.json', null, 'tsconfig.json')
|
|
|
|
:markdown
|
|
Our project should now look like this:
|
|
```
|
|
angular2-getting-started
|
|
├── node_modules
|
|
├── src
|
|
│ ├── app
|
|
│ ├── typings
|
|
│ │ ├── tsd.d.ts
|
|
│ ├── tsconfig.json
|
|
└── package.json
|
|
```
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Create an `index.html`
|
|
|
|
While in the **`src`** directory and
|
|
add a new `index.html` file with the following HTML
|
|
|
|
+makeExample('gettingstarted/ts/src/index.html', null, 'index.html',
|
|
{pnk: [/(angular2\.dev\.js)/, /(system\.src\.js)/, /(traceur-runtime\.js)/]})
|
|
|
|
.l-sub-section
|
|
:markdown
|
|
Notice in the `<head>` element that we're loading the scripts we installed earlier with npm.
|
|
|
|
There's an element called `<my-app>` in the `<body>`. This is a placeholder for the *root* of our
|
|
application. Angular will display our application content here.
|
|
|
|
The final inline script first configures the **`system.js`** module loader and then tells it
|
|
to import the JavaScript file named `app` in the `app/` folder.
|
|
|
|
Subsequent module imports are triggered by a cascade of `import` statements
|
|
beginning within `app.ts` itself.
|
|
|
|
**`app.ts`** is our main application file. We haven't written it yet. Let's do so now.
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Write the main application file, `app.ts`
|
|
|
|
**Change to the `src/app`** directory and **create an `app.ts` file**.
|
|
|
|
Add an empty class to it called `AppComponent` as follows:
|
|
|
|
+makeExample('gettingstarted/ts/src/app/app.ts', 'class')(format=".")
|
|
|
|
:markdown
|
|
We won't ask this class to do anything. It's just an empty, meaningless class until we tell
|
|
Angular about it by decorating it with some *annotations*.
|
|
|
|
Import the `component` and `view` *annotations* that we need from the Angular library at the top of the file:
|
|
|
|
+makeExample('gettingstarted/ts/src/app/app.ts', 'import')(format=".")
|
|
|
|
:markdown
|
|
Apply those annotations to the `AppComponent` class by writing the following lines
|
|
just above the class definition:
|
|
|
|
+makeExample('gettingstarted/ts/src/app/app.ts', 'class-w-annotations')
|
|
|
|
.l-sub-section
|
|
:markdown
|
|
TypeScript recognizes the `@` symbol as a prefix for a class annotation.
|
|
|
|
The **`@Component`** annotation tells Angular this class is a component
|
|
that controls the element named "my-app".
|
|
You may remember we added such an element to our *index.html* above.
|
|
|
|
The **`@View`** annotation identifies the "view" - the HTML template -
|
|
that defines the visual appearance of this component. We're writing the HTML template inline
|
|
in this example. Later we'll move the HTML to a view template file and
|
|
assign the template's filename to the `templateUrl`.
|
|
We'll prefer that practice for all but the most trivial templates.
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Bootstrap the app
|
|
|
|
Finally, we tell Angular to start running our app
|
|
with an instance of the `AppComponent` class as the root component.
|
|
We call this "bootstrapping the app".
|
|
|
|
+makeExample('gettingstarted/ts/src/app/app.ts', 'bootstrap')(format=".")
|
|
|
|
:markdown
|
|
Here is the complete `app.ts`
|
|
|
|
+makeExample('gettingstarted/ts/src/app/app.ts', null, 'app.ts')
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Confirm the final project and file structure
|
|
|
|
```
|
|
angular2-getting-started
|
|
├── node_modules
|
|
├── src
|
|
│ ├── app
|
|
│ │ ├── app.ts
|
|
│ ├── typings
|
|
│ │ ├── tsd.d.ts
|
|
│ ├── index.html
|
|
│ ├── tsconfig.json
|
|
└── package.json
|
|
```
|
|
Seems like overkill for such a trivial application.
|
|
|
|
We have ambitions. We aren't learning Angular to build "Hello, World". We intend
|
|
to build great apps and we anticipate adding meat to these bones
|
|
in the "Tour of Heroes" tutorial coming up very soon.
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Compile the TypeScript to JavaScript
|
|
|
|
We've written our app in TypeScript but the browser only understands JavaScript.
|
|
We must run the TypeScript compiler to produce JavaScript for the browser.
|
|
|
|
Open a terminal window in the **root of the application folder** (not *src*) and enter:
|
|
|
|
pre.prettyprint.lang-bash
|
|
code tsc -p src -w
|
|
|
|
:markdown
|
|
After it runs we should find the generated *app.js* file in the *src* folder and also an *app.map.js* file that
|
|
helps debuggers navigate between the JavaScript and the TypeScript source.
|
|
|
|
We gave *tsc* the watch option (`-w`). It will watch for changes to our *.ts* files and
|
|
recompile them automatically. Leave it running in this terminal window.
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## Run it!
|
|
|
|
Now we are ready to see this app in action.
|
|
|
|
Open a another terminal window in the **root of the application folder** (not *src*) and
|
|
launch a node static server such as the *live-server* we recommended earlier:
|
|
|
|
pre.prettyprint.lang-bash
|
|
code live-server --open=src
|
|
|
|
:markdown
|
|
**live-server** loads the browser for us, serves the HTML and JavaScript files, and we should see it display our
|
|
application message:
|
|
|
|
figure.image-display
|
|
img(src='/resources/images/examples/setup-example1.png' alt="Example of Todo App")
|
|
|
|
:markdown
|
|
### Make some changes
|
|
**live-server** detects changes to our files and refreshes the browser page for us automatically.
|
|
|
|
Try changing the message to "My SECOND Angular 2 app".
|
|
|
|
The TypeScript compiler running in the first terminal window is watching our source code. It recompiles and produces
|
|
the revised *app.js*. The *live-server* sees that change and reloads the browser.
|
|
|
|
Pretty nice!
|
|
|
|
.l-main-section
|
|
:markdown
|
|
## It's all a tree
|
|
|
|
We can think of Angular apps as a tree of components.
|
|
|
|
The `AppComponent` that we've been talking about acts as the top
|
|
level container - the root of the tree - for the rest of our application.
|
|
There's nothing special about the `AppComponent` name and we can use whatever makes sense to us.
|
|
|
|
We've pinned the root component to an element in the `index.html` file where our application will
|
|
render its view. The element is called `<my-app>` but there is nothing special about this
|
|
name either.
|
|
|
|
The *root component* loads the initial template for the application.
|
|
That template could load other components such as menu bars, views, and forms
|
|
that display information and respond to user gestures.
|
|
|
|
And these components could load yet more components until the browser page became a deep tree
|
|
of nested functionality.
|
|
|
|
We'll walk through examples of these scenarios in the following pages.
|