Setting up a project in Angular2 (rc6 and beyond)
Soon^1), there will be the angular-cli
command line tool, to automate the process of setting up a new project in Angular2. However, its still useful to understand what angular-cli
actually does. This is a quick walk-through, from start to final project set-up.
Create a directory (here "ng2-app"), cd
into it, and create a new empty npm
package, accepting all defaults.
mkdir ng2-app && cd $_ && npm init -y
Next, install the most recent Angular2 release into the directory, using npm
. For that, simply add all required packages to the packages.json
configuration file you just created. Your packages.json
should look like this
{
"name": "ng2-app",
"description": "Manual set-up Angular2 project.",
"private": true,
"scripts": {
"start": "live-server --mount=/:./src/ --entry-file=./src/index.html"
},
"dependencies": {
"@angular/common": "2.0.0-rc.6",
"@angular/compiler": "2.0.0-rc.6",
"@angular/core": "2.0.0-rc.6",
"@angular/forms": "2.0.0-rc.6",
"@angular/http": "2.0.0-rc.6",
"@angular/platform-browser": "2.0.0-rc.6",
"@angular/platform-browser-dynamic": "2.0.0-rc.6",
"@angular/router": "^3.0.0-rc.2",
"core-js": "^2.4.0",
"rxjs": "5.0.0-beta.11",
"systemjs": "0.19.37",
"zone.js": "0.6.17"
},
"devDependencies": {
"live-server": "^1.0.0",
"typescript": "^2.0.0"
}
}
To install all required packages, run npm install
in your project directory.
npm install
While the dependencies are installing, have a look at the above code. Especially at the line "scripts": { "start": "..." }
. Here, we define a command to run a development server that launches our Angular2 app in a browser. With --mount=/:./src/
the root path http://127.0.0.1/
is mapped to the ./src/
directory. And, very useful for one-page-apps, we will always serve the index.html
file for any path in the browser adress bar with --entry-file=./src/index.html
, because we want Angular2 to handle the routing. We will use this as npm start
at the end of this text.
After all dependencies have installed successfully, we now need to create some files:
- An
index.html
as the entry point to the application, - a
systemjs.config.js
as the central configuration file for Angular, - a
main.ts
as entry point for Angular2, - in
app.module.ts
will be the app's root module, and - in
app.component.ts
will be the app's initial component.
We will losely follow convention used by angular-cli
and use a subdirectory app/
for files that belong to the app itself. The file tree should be as follows
[ng2-app]
|
|-[src]
| |
| |-[app]
| | |
| | |- app.component.ts
| | |- app.module.ts
| | |- main.ts
| |
| |- index.html
| |- systemjs.config.js
|
|-[node_modules]
| |
| |-[@angular]
| |-[typescript]
| |- ...and a bazilion other directories...
|
|- package.json
Let's begin with the boilerplate for index.html
. This loads typescript.js
, the typescript JIT^2) compiler, shim.js
to fix up older browsers, zone.js
to get property bindings, and systemjs
and its config file, to get the who thing started up.
# -- ./src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="/">
<title>Angular2 project</title>
<script src="node_modules/typescript/lib/typescript.js"></script>
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err) });
</script>
</head>
<body><app>Loading...</app></body>
</html>
Next up is systemjs.config.js
that will tell the app loader what to do with all those files and functions, and where to find files that are imported by other files. Take a minute to look at it and understand what it does.
# -- ./src/systemjs.config.js
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
map: {
'@angular': 'node_modules/@angular',
'rxjs': 'node_modules/rxjs'
},
paths: {
'node_modules/@angular/*': 'node_modules/@angular/*/bundles'
},
meta: {
'@angular/*': {'format': 'cjs'}
},
packages: {
'app': { main: 'main', defaultExtension: 'ts' },
'rxjs': { main: 'Rx' },
'@angular/common': { main: 'common.umd.min.js' },
'@angular/compiler': { main: 'compiler.umd.min.js' },
'@angular/core': { main: 'core.umd.min.js' },
'@angular/forms': { main: 'forms.umd.min.js' },
'@angular/platform-browser': { main: 'platform-browser.umd.min.js' },
'@angular/platform-browser-dynamic': {
main: 'platform-browser-dynamic.umd.min.js'
}
}
});
Noticed the first line under packages: {}
where it defines app
? That refers to the next file: main.ts
. That's our TypeScript app's entry point, where the bootstrapping happens. Create the file in the app/
directory with the following boilerplate
// -- ./src/app/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
The module platformBrowserDynamic
does the JiT compiling of our app, so when your app is ready for deployment, you can just replace it by the AoT compiler call. The AppModule
it works on is your app's Root Module.
Every Angular2 app has one root module (though if you don't define one yourself, Angular2 will go ahead and create one for you automatically, so that's nice). But in this case, lets define a root module explicitly, and then a main component.
// -- ./src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
So far, a script in our index.html
has invoked the SystemJS loader, that called our main.ts
script, that invoked Angular2's bootstrap machine, feeding it our app's root module. Now, as a last step, our root module imports our main component's class AppComponent
and hands it to the bootstrap
field of NgModule.
Below is some boilerplate for app.component.ts
that you should replace with your actual app code
// -- ./src/app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app',
template: `<h1>The app works {{ status }}!</h1>`
})
export class AppComponent {
status: string;
constructor() {
this.status = 'great';
}
}
That was all. Remember "scripts": { "start": "..." }
from the package.json
file? Now is the time. In the project's root directory, run
npm start
If all goes well, this opens a new tab in your default browser with the output of the app. From here, you can start writing your Angular2 app.
Sources, tutorials, docs
- Udemy: The Complete Angular 2 With Typescript Course
- Official Angular2 tutorial
- Angular2 tag on StackOverflow
- Official Typescript documentation
- More useful settings for the npm live-server
1) Probably shortly after the Angular2 Summit in Boston from 26-28 September 2016.
2) Just-in-time compilation compiles the app in the browser. Good for development, but slow for production. With rc6, Angular got an easily usable AoT (ahead-of-time) compiler as well, that should be used for production in most cases.