Set the minimum typescript version to 1.5.0
fixes #172 ^1.5.0-beta means >= 1.5.0 and < 2.0.0 and is technically valid. however it's probably nicer not to refer to beta versions in the doc.
This commit is contained in:
parent
e38fc6b3a9
commit
ac2bfed40d
|
@ -1,580 +1,260 @@
|
|||
include _util-fns
|
||||
.callout.is-helpful
|
||||
header Angular is in developer preview
|
||||
p.
|
||||
This quickstart does not reflect the final development process for writing apps with Angular.
|
||||
The following setup is for those who want to try out Angular while it is in developer preview.
|
||||
|
||||
:marked
|
||||
Let's start from zero and build a super simple Angular application in JavaScript.
|
||||
// STEP 1 - Create a project ##########################
|
||||
.l-main-section
|
||||
h2#section-create-project 1. Create a project
|
||||
|
||||
p.
|
||||
This quickstart shows how to write your Angular components in TypeScript. You could instead choose
|
||||
another language such as <a href="/docs/dart/latest/quickstart.html">Dart</a>, ES5, or ES6.
|
||||
|
||||
p.
|
||||
The goal of this quickstart is to write a component in TypeScript that prints a string.
|
||||
We assume you have already installed <a href="https://docs.npmjs.com/getting-started/installing-node">Node and npm</a>.
|
||||
|
||||
p.
|
||||
To get started, create a new empty project directory. All the following commands should be run
|
||||
from this directory.
|
||||
|
||||
p.
|
||||
To get the benefits of TypeScript, we want to have the type definitions available for the compiler and the editor.
|
||||
TypeScript type definitions are typically published in a repo called <a href="http://definitelytyped.org/">DefinitelyTyped</a>.
|
||||
To fetch one of the type definitions to the local directory, we use the <a href="https://www.npmjs.com/package/tsd">tsd package manager</a>.
|
||||
|
||||
code-example.
|
||||
$ npm install -g tsd@^0.6.0
|
||||
$ tsd install angular2 es6-promise rx rx-lite
|
||||
|
||||
p.
|
||||
Next, create two empty files, <code>index.html</code> and <code>app.ts</code>, both at the root of the project:
|
||||
|
||||
code-example.
|
||||
$ touch app.ts index.html
|
||||
|
||||
// STEP 2 - Start the TypeScript compiler ##########################
|
||||
.l-main-section
|
||||
h2#start-tsc 2. Run the TypeScript compiler
|
||||
|
||||
p.
|
||||
Since the browser doesn't understand TypeScript code, we need to run a compiler to translate
|
||||
your code to browser-compliant JavaScript as you work. This quickstart uses the TypeScript
|
||||
compiler in <code>--watch</code> mode, but it is also possible to do the translation in the browser as files
|
||||
are loaded, or configure your editor or IDE to do it.
|
||||
|
||||
code-example.
|
||||
$ npm install -g typescript@^1.5.0
|
||||
$ tsc --watch -m commonjs -t es5 --emitDecoratorMetadata app.ts
|
||||
|
||||
.callout.is-helpful
|
||||
header Don't want JavaScript?
|
||||
:marked
|
||||
Although we're getting started in JavaScript, you can also write Angular apps
|
||||
in TypeScript by selecting it from the combo-box in the banner.
|
||||
p.
|
||||
Windows users: if you get an error that an option is unknown, you are probably running
|
||||
an older version of TypeScript.
|
||||
See <a href="http://stackoverflow.com/questions/23267858/how-do-i-install-typescript">
|
||||
Stack Overflow: How do I install Typescript</a>
|
||||
|
||||
// STEP 3 - Import Angular ##########################
|
||||
.l-main-section
|
||||
:marked
|
||||
## See It Run!
|
||||
h2#section-transpile 3. Import Angular
|
||||
|
||||
Running the <live-example></live-example>
|
||||
is the quickest way to see an Angular app come to life.
|
||||
|
||||
Clicking that link fires up a browser, loads the sample in [plunker](http://plnkr.co/ "Plunker"),
|
||||
and displays a simple message:
|
||||
p Inside of <code>app.ts</code>, import the type definitions from Angular:
|
||||
code-example.
|
||||
/// <reference path="typings/angular2/angular2.d.ts" />
|
||||
|
||||
figure.image-display
|
||||
img(src='/resources/images/devguide/quickstart/hello-angular.png' alt="Output of quickstart app")
|
||||
:marked
|
||||
Here is the file structure:
|
||||
.filetree
|
||||
.file angular-quickstart
|
||||
.children
|
||||
.file src
|
||||
.children
|
||||
.file app
|
||||
.children
|
||||
.file app.component.js
|
||||
.file app.module.js
|
||||
.file main.js
|
||||
.file index.html
|
||||
.file styles.css
|
||||
:marked
|
||||
Functionally, it's an `index.html`, `styles.css` and three JavaScript files in an `app/` folder.
|
||||
We can handle that!
|
||||
|
||||
Of course we won't build many apps that only run in plunker.
|
||||
Let's follow a process that's closer to what we'd do in real life.
|
||||
|
||||
1. Set up our development environment
|
||||
1. Write the Angular root component for our app
|
||||
1. Add an Angular Module
|
||||
1. Bootstrap it to take control of the main web page
|
||||
1. Write the main page (`index.html`)
|
||||
1. Add some CSS (`styles.css`)
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
We really can build the QuickStart from scratch in five minutes
|
||||
if we follow the instructions and ignore the commentary.
|
||||
|
||||
Most of us will be interested in the "why" as well as the "how" and that will take longer.
|
||||
p Now your editor should be able to complete the available imports:
|
||||
code-example.
|
||||
import {Component, View, bootstrap} from 'angular2/angular2';
|
||||
|
||||
p.
|
||||
The above import statement uses ES6 module syntax to import three symbols from the Angular module.
|
||||
The module will load at runtime.
|
||||
|
||||
|
||||
// STEP 4 - Create a component ##########################
|
||||
.l-main-section
|
||||
:marked
|
||||
## Development Environment
|
||||
|
||||
We'll need a place to stand (the application project folder), some libraries
|
||||
and your editor of choice.
|
||||
|
||||
### Create a new project folder
|
||||
|
||||
code-example(format="").
|
||||
mkdir angular-quickstart
|
||||
cd angular-quickstart
|
||||
:marked
|
||||
### Add the libraries we need
|
||||
|
||||
We recommend the **npm** package manager for acquiring and managing our development libraries.
|
||||
h2#section-angular-create-account 4. Define a component
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Don't have npm?
|
||||
[Get it now](https://docs.npmjs.com/getting-started/installing-node "Installing Node.js and updating npm")
|
||||
because we're going to use it now and repeatedly throughout this documentation.
|
||||
:marked
|
||||
Add a **package.json** file to the project folder and copy/paste the following:
|
||||
+makeJson('quickstart/js/package.1.json', null, 'package.json')(format=".")
|
||||
p.
|
||||
Components structure and represent the UI. This quickstart demonstrates the process of creating a component
|
||||
that has an HTML tag named <strong><code><my-app></code></strong>.
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Itching to know the details? We explain in the [appendix below](#package-json)
|
||||
:marked
|
||||
Install these packages by opening a terminal window (command window in Windows) and
|
||||
running this npm command.
|
||||
code-example(format="").
|
||||
npm install
|
||||
:marked
|
||||
.l-sub-section
|
||||
:marked
|
||||
Scary <span style="color:red; font-weight: bold">error messages in red</span> may appear **during** install.
|
||||
Ignore them. The install will succeed. See the [appendix below](#npm-errors) for more information.
|
||||
p.
|
||||
A component consists of two parts, the <strong>component controller</strong>
|
||||
which is an ES6 class, and the <strong>decorators</strong> which tell Angular
|
||||
how to place the component into the page.
|
||||
|
||||
code-example(language="javascript" format="linenums").
|
||||
// Annotation section
|
||||
@Component({
|
||||
selector: 'my-app'
|
||||
})
|
||||
@View({
|
||||
template: '<h1>Hello {{ name }}</h1>'
|
||||
})
|
||||
// Component controller
|
||||
class MyAppComponent {
|
||||
name: string;
|
||||
|
||||
constructor() {
|
||||
this.name = 'Alice';
|
||||
}
|
||||
}
|
||||
|
||||
.l-sub-section
|
||||
h3 @Component and @View annotations
|
||||
|
||||
p.
|
||||
A component annotation describes details about the component. An annotation can be identified by its at-sign (<code>@</code>).
|
||||
p.
|
||||
The <code>@Component</code> annotation defines the HTML tag for the component by specifying the component's CSS selector.
|
||||
p.
|
||||
The <code>@View</code> annotation defines the HTML that represents the component. The component you wrote uses an inline template, but you can also have an external template. To use an external template, specify a <code>templateUrl</code> property and give it the path to the HTML file.
|
||||
|
||||
code-example(language="javascript" format="linenums").
|
||||
@Component({
|
||||
selector: 'my-app' // Defines the <my-app></my-app> tag
|
||||
})
|
||||
@View({
|
||||
template: '<h1>Hello {{ name }}</h1>' // Defines the inline template for the component
|
||||
})
|
||||
|
||||
p.
|
||||
The annotations above specify an HTML tag of <code><my-app></code>
|
||||
and a template of <code ng-non-bindable><h1>Hello {{ name }}</h1></code>.
|
||||
|
||||
.l-sub-section
|
||||
h3 The template and the component controller
|
||||
|
||||
p.
|
||||
The component controller is the backing of the component's template. This component
|
||||
controller uses TypeScript <code>class</code> syntax.
|
||||
|
||||
code-example(language="javascript" format="linenums").
|
||||
class MyAppComponent {
|
||||
name: string;
|
||||
constructor() {
|
||||
this.name = 'Alice';
|
||||
}
|
||||
}
|
||||
|
||||
p.
|
||||
Templates read from their component controllers. Templates have access to any properties
|
||||
or functions placed on the component controller.
|
||||
|
||||
p.
|
||||
The template above binds to a <code>name</code> property through
|
||||
the double-mustache syntax (<code ng-non-bindable>{{ ... }}</code>).
|
||||
The body of the constructor assigns "Alice" to the name property. When the
|
||||
template renders, "Hello Alice" appears instead of
|
||||
<span ng-non-bindable>"Hello {{ name }}"</span>.
|
||||
|
||||
|
||||
|
||||
// STEP 5 - Bootstrap ##########################
|
||||
.l-main-section
|
||||
:marked
|
||||
## Our First Angular Component
|
||||
|
||||
The *Component* is the most fundamental of Angular concepts.
|
||||
A component manages a view - a piece of the web page where we display information
|
||||
to the user and respond to user feedback.
|
||||
|
||||
Technically, a component is a class that controls a view template.
|
||||
We'll write a lot of them as we build Angular apps. This is our first attempt
|
||||
so we'll keep it ridiculously simple.
|
||||
|
||||
### Create an application source sub-folder
|
||||
|
||||
We like to keep our application code in a sub-folder off the root called `src/app/`.
|
||||
Execute the following command in the console window.
|
||||
code-example(format="").
|
||||
mkdir app
|
||||
cd app
|
||||
:marked
|
||||
### Add the component file
|
||||
Now add a file named **app.component.js** and paste the following lines:
|
||||
+makeExample('quickstart/js/src/app/app.component.js', null, 'src/app/app.component.js')(format=".")
|
||||
:marked
|
||||
We're creating a visual component named **`AppComponent`** by chaining the
|
||||
`Component` and `Class` methods that belong to the **global Angular core namespace, `ng.core`**.
|
||||
|
||||
+makeExample('quickstart/js/src/app/app.component.js', 'ng-namespace-funcs', 'src/app/app.component.js ' +
|
||||
'(component schema)')(format=".")
|
||||
h2#section-transpile 5. Bootstrap
|
||||
|
||||
:marked
|
||||
The **`Component`** method takes a configuration object with three
|
||||
properties. The **`Class`** method is where we implement the component itself,
|
||||
giving it properties and methods that bind to the view and whatever
|
||||
behavior is appropriate for this part of the UI.
|
||||
|
||||
Let's review this file in detail.
|
||||
p.
|
||||
At the bottom of <code>app.ts</code>, call the <code>bootstrap()</code> function
|
||||
to load your new component into its page:
|
||||
|
||||
### Modules
|
||||
Angular apps are modular. They consist of many files each dedicated to a purpose.
|
||||
|
||||
ES5 JavaScript doesn't have a native module system.
|
||||
There are several popular 3rd party module systems we could use.
|
||||
Instead, for simplicity and to avoid picking favorites,
|
||||
we'll create a single global namespace for our application.
|
||||
|
||||
We'll call it `app` and we'll add all of our code artifacts to this one global object.
|
||||
|
||||
We don't want to pollute the global namespace with anything else.
|
||||
So within each file we surround the code in an IIFE ("Immediately Invoked Function Expression").
|
||||
|
||||
+makeExample('quickstart/js/src/app/app.component.js', 'iife', 'src/app/app.component.js (IIFE)')(format=".")
|
||||
|
||||
:marked
|
||||
We pass the global `app` namespace object into the IIFE,
|
||||
taking care to initialize it with an empty object if it doesn't yet exist.
|
||||
|
||||
Most application files *export* one thing by adding that thing to the `app` namespace.
|
||||
Our `app.component.js` file exports the `AppComponent`.
|
||||
|
||||
+makeExample('quickstart/js/src/app/app.component.js', 'export', 'src/app/app.component.js (export)')(format=".")
|
||||
|
||||
:marked
|
||||
A more sophisticated application would have child components that descended from
|
||||
`AppComponent` in a visual tree.
|
||||
A more sophisticated app would have more files and modules, at least as many as it had components.
|
||||
|
||||
Quickstart isn't sophisticated; one component is all we need.
|
||||
Yet modules play a fundamental organizational role in even this small app.
|
||||
|
||||
Modules rely on other modules. In JavaScript Angular apps, when we need something
|
||||
provided by another module, we get it from the `app` object.
|
||||
When another module needs to refer to `AppComponent`, it gets it from the `app.AppComponent` like this:
|
||||
|
||||
+makeExample('quickstart/js/src/app/app.module.js', 'import', 'src/app/app.module.js (import)')(format=".")
|
||||
code-example(language="javaScript").
|
||||
bootstrap(MyAppComponent);
|
||||
|
||||
:marked
|
||||
Angular is also modular. It is a collection of library modules.
|
||||
Each library is itself a module made up of several, related feature modules.
|
||||
|
||||
When we need something from Angular, we use the `ng` object.
|
||||
|
||||
:marked
|
||||
### The Class definition object
|
||||
At the bottom of the file is an empty, do-nothing class definition object for
|
||||
our `AppComponent` class.
|
||||
When we're ready to build a substantive application,
|
||||
we can expand this object with properties and application logic.
|
||||
Our `AppComponent` class has nothing but an empty constructor because we
|
||||
don't need it to do anything in this QuickStart.
|
||||
|
||||
+makeExample('quickstart/js/src/app/app.component.js', 'class','app.component.js (class)')(format=".")
|
||||
|
||||
:marked
|
||||
### The Component definition object
|
||||
`ng.core.Component()` tells Angular that this class definition object
|
||||
*is an Angular component*.
|
||||
The configuration object passed to the `ng.core.Component()` method has two
|
||||
fields, a `selector` and a `template`.
|
||||
|
||||
+makeExample('quickstart/js/src/app/app.component.js', 'component','app.component.js (component)')(format=".")
|
||||
|
||||
:marked
|
||||
The `selector` specifies a simple CSS selector for a host HTML element named `my-app`.
|
||||
Angular creates and displays an instance of our `AppComponent`
|
||||
wherever it encounters a `my-app` element in the host HTML.
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
Remember the `my-app` selector! We'll need that information when we write our `index.html`
|
||||
:marked
|
||||
The `template` property holds the component's companion template.
|
||||
A template is a form of HTML that tells Angular how to render a view.
|
||||
Our template is a single line of HTML announcing "Hello Angular".
|
||||
|
||||
Now we need something to tell Angular to load this component.
|
||||
p.
|
||||
The <code>bootstrap()</code> function takes a
|
||||
component as a parameter, enabling the component
|
||||
(as well as any child components it contains) to render.
|
||||
|
||||
### Add an NgModule
|
||||
|
||||
Angular apps are composed of [Angular Modules](guide/ngmodule.html) that
|
||||
snuggly contain all our components and everything else we need for our app.
|
||||
|
||||
Create the `src/app/app.module.js` file with the following content:
|
||||
|
||||
+makeExample('quickstart/js/src/app/app.module.js', null, 'src/app/app.module.js')
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Read more about the `NgModule` configuration in the [appendix below](#ngmodule).
|
||||
|
||||
:marked
|
||||
### Bootstrap it!
|
||||
|
||||
Add a new file , `main.js`, to the `src/app/` folder as follows:
|
||||
+makeExample('quickstart/js/src/main.js', null, 'src/main.js')(format=".")
|
||||
:marked
|
||||
We need two things to launch the application:
|
||||
1. Angular's `platformBrowserDynamic().bootstrapModule` function
|
||||
1. The application root module that we just wrote.
|
||||
|
||||
We have them both in our 'namespaces'.
|
||||
Then we call `bootstrapModule`, passing in the **root app module**, `AppModule`.
|
||||
|
||||
.l-sub-section
|
||||
:marked
|
||||
Learn why we need `bootstrapModule` from `ng.platformBrowserDynamic`
|
||||
and why we create a separate js files in the [appendix below](#main).
|
||||
:marked
|
||||
We've asked Angular to launch the app in a browser with our component at the root.
|
||||
Where will Angular put it?
|
||||
|
||||
// STEP 6 - Declare the HTML ##########################
|
||||
.l-main-section
|
||||
:marked
|
||||
## Add the `index.html`
|
||||
|
||||
Angular displays our application in a specific location on our `index.html`.
|
||||
It's time to create that file.
|
||||
|
||||
We won't put our `index.html` in the `src/app/` folder.
|
||||
We'll locate it **up one level, in the project root folder**.
|
||||
|
||||
code-example(format="").
|
||||
cd ..
|
||||
:marked
|
||||
Now create the`index.html` file and paste the following lines:
|
||||
+makeExample('quickstart/js/src/index.html', null, 'src/index.html')(format=".")
|
||||
:marked
|
||||
There are three noteworthy sections of HTML:
|
||||
h2#section-angular-create-account 6. Declare the HTML
|
||||
|
||||
1. We load the JavaScript libraries we need; learn about them [below](#libraries).
|
||||
p.
|
||||
Inside the <code>head</code> tag of <code>index.html</code>,
|
||||
include the traceur-runtime and the Angular bundle.
|
||||
Instantiate the <code>my-app</code> component in the <code>body</code>.
|
||||
|
||||
2. We load our JavaScript files.
|
||||
code-example(language="html" format="linenums").
|
||||
<!-- index.html -->
|
||||
<html>
|
||||
<head>
|
||||
<title>Angular 2 Quickstart</title>
|
||||
<script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87/traceur-runtime.js"></script>
|
||||
<script src="https://code.angularjs.org/2.0.0-alpha.28/angular2.dev.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
3. We add the `<my-app>` tag in the `<body>`. **This is where our app lives!**
|
||||
|
||||
When Angular calls the `bootstrapModule` function in `main.js`,
|
||||
it reads the `AppModule` metadata, sees that `AppComponent` is the bootstrap component,
|
||||
finds the `my-app` selector, locates an element tag named `my-app`,
|
||||
and renders our application's view between those tags.
|
||||
<!-- The app component created in app.ts -->
|
||||
<my-app></my-app>
|
||||
|
||||
: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/_boilerplate/styles.css).
|
||||
+makeExample('quickstart/js/src/styles.1.css', null, 'src/styles.css')(format=".")
|
||||
|
||||
:marked
|
||||
### Configure the server
|
||||
We're going to use a static server called **lite-server** that loads `index.html` in a browser
|
||||
and refreshes the browser when application files change.
|
||||
|
||||
The static server will use the `bs-config.json` file as configuration.
|
||||
This files tells the server that `src/` is the base directory to serve, and that any
|
||||
requests to `node_modules/` should be routed to `node_modules/` in the root directory
|
||||
instead of `src/node_modules/`
|
||||
</body>
|
||||
</html>
|
||||
|
||||
// STEP 7 - Declare the HTML ##########################
|
||||
.l-main-section
|
||||
:marked
|
||||
## Run!
|
||||
|
||||
Open a terminal window and enter this command:
|
||||
code-example(format="").
|
||||
npm start
|
||||
:marked
|
||||
That command runs **lite-server**.
|
||||
|
||||
In a few moments, a browser tab should open and display
|
||||
|
||||
figure.image-display
|
||||
img(src='/resources/images/devguide/quickstart/hello-angular.png' alt="Output of quickstart app")
|
||||
h2#section-load-component-module 7. Load the component
|
||||
|
||||
:marked
|
||||
Congratulations! We are in business.
|
||||
p.
|
||||
The last step is to load the module for the <code>my-app</code> component.
|
||||
To do this, we'll use the System library.
|
||||
|
||||
.alert.is-helpful
|
||||
:marked
|
||||
If you see `Loading...` displayed instead, see the
|
||||
[Browser ES2015 support appendix](#es6support).
|
||||
:marked
|
||||
### Make some changes
|
||||
|
||||
Try changing the message to "Hello Angular!".
|
||||
|
||||
`lite-server` is watching, so it should detect the change,
|
||||
refresh the browser, and display the revised message.
|
||||
.l-sub-section
|
||||
h3 System.js
|
||||
|
||||
It's a nifty way to develop an application!
|
||||
|
||||
We close the terminal window when we're done to terminate the server.
|
||||
p.
|
||||
<a href="https://github.com/systemjs/systemjs">System</a> is a third-party open-source library that
|
||||
adds ES6 module loading functionality to browsers.
|
||||
|
||||
p.
|
||||
Add the System.js dependency in the <code><head></code> tag, so that
|
||||
it looks like:
|
||||
|
||||
code-example(language="html" format="linenums").
|
||||
<head>
|
||||
<title>Angular 2 Quickstart</title>
|
||||
<script src="https://github.jspm.io/jmcriffey/bower-traceur-runtime@0.0.87/traceur-runtime.js"></script>
|
||||
<script src="https://jspm.io/system@0.16.js"></script>
|
||||
<script src="https://code.angularjs.org/2.0.0-alpha.28/angular2.dev.js"></script>
|
||||
</head>
|
||||
|
||||
p.
|
||||
Add the following module-loading code:
|
||||
|
||||
code-example(language="html" format="linenums").
|
||||
<my-app></my-app>
|
||||
<script>System.import('app');</script>
|
||||
|
||||
|
||||
// STEP 8 - Run a local server ##########################
|
||||
.l-main-section
|
||||
:marked
|
||||
## Final structure
|
||||
Our final project folder structure looks like this:
|
||||
.filetree
|
||||
.file angular-quickstart
|
||||
.children
|
||||
.file node_modules
|
||||
.file src
|
||||
.children
|
||||
.file app
|
||||
.children
|
||||
.file app.component.js
|
||||
.file app.module.js
|
||||
.file main.js
|
||||
.file index.html
|
||||
.file styles.css
|
||||
.file bs-config.json
|
||||
.file package.json
|
||||
:marked
|
||||
And here are the files:
|
||||
+makeTabs(`
|
||||
quickstart/js/src/app/app.component.js,
|
||||
quickstart/js/src/app/app.module.js,
|
||||
quickstart/js/src/main.js,
|
||||
quickstart/js/src/index.html,
|
||||
quickstart/js/src/styles.1.css,
|
||||
quickstart/js/bs-config.1.json,
|
||||
quickstart/js/package.1.json
|
||||
`,null,
|
||||
`src/app/app.component.js,
|
||||
src/app/app.module.js,
|
||||
src/main.js,
|
||||
src/index.html,
|
||||
src/styles.css,
|
||||
bs-config.json,
|
||||
package.json
|
||||
`)
|
||||
|
||||
h2#section-load-component-module 8. Run a local server
|
||||
|
||||
p Run a local HTTP server, and view <code>index.html</code>.
|
||||
|
||||
p.
|
||||
If you don't already have an HTTP server,
|
||||
you can install one using <code>npm install -g http-server</code>.
|
||||
(If that results in an access error, then you might need to use
|
||||
<code><b>sudo</b> npm ...</code>)
|
||||
For example:
|
||||
|
||||
code-example.
|
||||
# From the directory that contains index.html:
|
||||
npm install -g http-server # Or sudo npm install -g http-server
|
||||
http-server # Creates a server at localhost:8080
|
||||
# In a browser, visit localhost:8080/index.html
|
||||
|
||||
|
||||
// WHAT'S NEXT... ##########################
|
||||
.l-main-section
|
||||
:marked
|
||||
## Wrap Up
|
||||
Our first application doesn't do much. It's basically "Hello, World" for Angular.
|
||||
|
||||
We kept it simple in our first pass: we wrote a little Angular component,
|
||||
we added some JavaScript libraries to `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.**
|
||||
|
||||
The good news is that the overhead of setup is (mostly) behind us.
|
||||
We'll probably only touch the `package.json` to update libraries.
|
||||
Besides adding in the script files for our app 'modules',
|
||||
we'll likely open `index.html` only if we need to add a library or some css stylesheets.
|
||||
|
||||
We're about to take the next step and build a small application that
|
||||
demonstrates the great things we can build with Angular.
|
||||
|
||||
Join us on the [Tour of Heroes Tutorial](./tutorial)!
|
||||
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
## Appendices
|
||||
The balance of this chapter is a set of appendices that
|
||||
elaborate some of the points we covered quickly above.
|
||||
|
||||
There is no essential material here. Continued reading is for the curious.
|
||||
|
||||
<a id="ie-polyfills"></a>
|
||||
<a id="es6support"></a>
|
||||
<a id="libraries"></a>
|
||||
.l-main-section
|
||||
:marked
|
||||
### Appendix: Libraries
|
||||
We loaded the following scripts
|
||||
+makeExample('quickstart/js/src/index.html', 'libraries', 'src/index.html')(format=".")
|
||||
:marked
|
||||
We began with an Internet Explorer polyfill.
|
||||
IE requires a polyfill to run
|
||||
an application that relies on ES2015 promises and dynamic module loading.
|
||||
Most applications need those capabilities and most applications
|
||||
should run in Internet Explorer.
|
||||
|
||||
Next are the polyfills for Angular, `zone.js` and `Reflect.js`,
|
||||
followed by the Reactive Extensions RxJS library.
|
||||
.l-sub-section
|
||||
:marked
|
||||
Our QuickStart doesn't use the Reactive Extensions
|
||||
but any substantial application will want them
|
||||
when working with observables.
|
||||
We added the library here in QuickStart so we don't forget later.
|
||||
:marked
|
||||
Finally, we loaded the web development version of Angular itself.
|
||||
|
||||
We'll make different choices as we gain experience and
|
||||
become more concerned about production qualities such as
|
||||
load times and memory footprint.
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
<a id="package-json"></a>
|
||||
### Appendix: package.json
|
||||
|
||||
[npm](https://docs.npmjs.com/) is a popular package manager and Angular application developers rely on it
|
||||
to acquire and manage the libraries their apps require.
|
||||
|
||||
We specify the packages we need in an npm [package.json](https://docs.npmjs.com/files/package.json) file.
|
||||
|
||||
The Angular team suggests the packages listed in the `dependencies` and `devDependencies`
|
||||
sections listed in this file:
|
||||
|
||||
+makeJson('quickstart/js/package.1.json',{ paths: 'dependencies, devDependencies'}, 'package.json (dependencies)')(format=".")
|
||||
:marked
|
||||
.l-sub-section
|
||||
:marked
|
||||
There are other possible package choices.
|
||||
We're recommending this particular set that we know work well together.
|
||||
Play along with us for now.
|
||||
Feel free to make substitutions later to suit your tastes and experience.
|
||||
:marked
|
||||
A `package.json` has an optional **scripts** section where we can define helpful
|
||||
commands to perform development and build tasks.
|
||||
We've included a number of such scripts in our suggested `package.json`:
|
||||
+makeJson('quickstart/js/package.1.json',{ paths: 'scripts'}, 'package.json (scripts)')(format=".")
|
||||
:marked
|
||||
We've seen how we can run the server with this command:
|
||||
code-example(format="").
|
||||
npm start
|
||||
:marked
|
||||
We are using the special `npm start` command, but all it does is run `npm run lite`.
|
||||
|
||||
We execute npm scripts in that manner: `npm run` + *script-name*. Here's what these scripts do:
|
||||
|
||||
* `npm run lite` - run the [lite-server](https://www.npmjs.com/package/lite-server),
|
||||
a light-weight, static file server, written and maintained by [John Papa](http://johnpapa.net/)
|
||||
with excellent support for Angular apps that use routing.
|
||||
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
<a id="npm-errors"></a>
|
||||
### Appendix: 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 re-compile itself using `node-gyp`.
|
||||
If the re-compile fails, the package recovers (typically with a pre-built version)
|
||||
and everything works.
|
||||
|
||||
Just make sure there are no `npm ERR!` messages at the very end of `npm install`.
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
<a id="ngmodule"></a>
|
||||
### Appendix: ***NgModule***
|
||||
The `NgModule` decorator is listing:
|
||||
|
||||
1. What other Angular Modules ours uses
|
||||
1. Which components and directives we declare in our components
|
||||
1. The component to bootstrap at the start
|
||||
|
||||
We import our lone `app.AppComponent` and add it to both `declarations` and `bootstrap` array.
|
||||
|
||||
Notice that we also add `ng.platformBrowser.BrowserModule` to the `imports` array.
|
||||
This is the Angular Module that contains all the needed Angular bits and pieces to run our app in the browser.
|
||||
|
||||
Angular itself is split into separate Angular Modules so we only need to import the ones we really use.
|
||||
|
||||
One of the most common ones is `FormsModule`, and soon we'll also see `RouterModule` and `HttpModule`.
|
||||
|
||||
.l-main-section
|
||||
:marked
|
||||
<a id="main"></a>
|
||||
### Appendix: ***main.js***
|
||||
|
||||
#### Bootstrapping is platform-specific
|
||||
We use the `platformBrowserDynamic().bootstrapModule` function from `ng.platformBrowserDynamic`,
|
||||
not `ng.core`. There's a good reason.
|
||||
|
||||
We only call "core" those capabilities that are the same across all platform targets.
|
||||
True, most Angular applications run only in a browser and we'll call the bootstrap function from
|
||||
this library most of the time. It's pretty "core" if we're always writing for a browser.
|
||||
|
||||
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 do we create a separate ***main.js***, ***app.module.js*** and ***app.component.js*** files?
|
||||
|
||||
The *main.js* file is tiny. This is just a QuickStart.
|
||||
We could have folded its few lines into the `app.module.js` file, and that one into
|
||||
`app.component.js` and spared ourselves some complexity.
|
||||
|
||||
We didn't for what we believe to be good reasons:
|
||||
1. Doing it right is easy
|
||||
1. Testability
|
||||
1. Reusability
|
||||
1. Separation of concerns
|
||||
1. We learned about import and export
|
||||
|
||||
#### It's easy
|
||||
Sure it's an extra step and an extra file. How hard is that in the scheme of things?
|
||||
|
||||
We'll see that a separate `main.js` and `app.module.js` is beneficial for *most* apps
|
||||
even if it isn't critical for the QuickStart.
|
||||
Let's develop good habits now while the cost is low.
|
||||
|
||||
#### Testability
|
||||
We should be thinking about testability from the beginning
|
||||
even if we know we'll never test the QuickStart.
|
||||
|
||||
It is difficult to unit test a component when there is a call to `bootstrapModule` in the same file.
|
||||
As soon as we load the component file to test the component,
|
||||
the `bootstrapModule` function tries to load the application in the browser.
|
||||
It throws an error because we're not expecting to run the entire application,
|
||||
just test the component.
|
||||
|
||||
Relocating the `bootstrapModule` function to `main.js` eliminates this spurious error
|
||||
and leaves us with a clean component module file.
|
||||
|
||||
#### Reusability
|
||||
We refactor, rename, and relocate files as our application evolves.
|
||||
We can't do any of those things while the file calls `bootstrapModule`.
|
||||
we can't move it.
|
||||
We can't reuse the component in another application.
|
||||
We can't pre-render the component on the server for better performance.
|
||||
|
||||
#### Separation of concerns
|
||||
A component's responsibility is to present and manage a view, and a NgModule's
|
||||
reponsibility is to define the application context.
|
||||
|
||||
Launching the application has nothing to do with any of these.
|
||||
That's a separate concern. The friction we're encountering in testing and reuse
|
||||
stems from this unnecessary mix of responsibilities.
|
||||
|
||||
#### Import/Export
|
||||
|
||||
While writing a separate `main.js` and `app.module.js` files we learned an essential Angular skill:
|
||||
how to 'export' from one 'module' and 'import' into another via our simple
|
||||
namespace abstraction.
|
||||
We'll do a lot of that as we learn more Angular.
|
||||
h2#section-transpile Great job! We'll have the next steps out soon.
|
||||
|
|
Loading…
Reference in New Issue