01. Initialisation : Installation des librairies et compilation avec TypeScript
J’ai divisé l’initialisation du projet en deux parties. Dans cette première partie, nous allons nous concentrer sur la récupération des librairies Angular 2 et la compilation du TypeScript pour créer une première page.
Les dépendances
Angular 2 est développé de manière modulaire et suis les préceptes modernes en terme d’architecture JavaScript. On ne va donc pas simplement installer un fichier JS mais récupérer plusieurs dépendances qui seront chargées en fonction de nos besoins. Initions donc un nouveau projet, pour cela créons un nouveau répertoire et utilisons NPM :
$> npm init –y
Pour ceux qui ne connaisse pas NPM, vous devrez en préambule regarder la leçon sur les bases de NPM.
Pour connaître la liste des dépendances et leur version, le plus simple est d’aller dans la documentation d’Angular et de récupérer la liste dans la section quickstart Nous ne récupérons que les dépendances pour le projet; pour les dépendances de développement nous en installerons 3 :
- typescript que nous utiliserons comme langage de développement à la place de JavaScript. C’est un sur-ensemble au JS qui offre notamment le typage
- typings utilisé par TypeScript, permet de gérer des fichiers servant à décrire les librairies externes
- lite-server un serveur web pour faire fonctionner notre application
Ce qui nous donnera le package.json suivant :
{
"name": "showtheque-angular2",
"version": "1.0.0",
"description": "ShowTheque avec Angular 2",
"main": "index.html",
"scripts": {
},
"dependencies": {
"@angular/common": "~2.1.1",
"@angular/compiler": "~2.1.1",
"@angular/core": "~2.1.1",
"@angular/forms": "~2.1.1",
"@angular/http": "~2.1.1",
"@angular/platform-browser": "~2.1.1",
"@angular/platform-browser-dynamic": "~2.1.1",
"@angular/router": "~3.1.1",
"@angular/upgrade": "~2.1.1",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.8",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.39",
"zone.js": "^0.6.25"
},
"devDependencies": {
"lite-server": "^2.2.2",
"typescript": "^2.0.6",
"typings": "1.5.0"
}
}
Il ne reste plus qu'a récupérer tous ces packages avec NPM :
$> npm install
Comme nous travaillons en local nous allons devoir ajouter dans la section scripts, les 3 dépendances de développement qui fonctionnent en ligne de commande:
{
"scripts": {
"tsc": "tsc",
"typings": "typings",
"server": "lite-server"
}
}
Configuration des modules
Comme je le disais, nous n’allons pas inclure directement Angular mais utiliser un système de module qui permettra de charger les portions d’Angular dont nous avons besoin. Pour cela, nous utiliserons comme outil systemjs. Pour ce faire, il faut créer un fichier de configuration systemjs.config.js dont le contenu peut être également récupéré depuis la documentation d’Angular :
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
'@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
// others libraries
'rxjs': 'npm:rxjs'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
En résumé, on indique à systemjs où récupérer les différents modules, puis on déclare une application app dont le point d'entrée sera par la suite contenu dans un fichier main.js.
Création de la page principale et ajout des librairies
Créons à la racine, une page HTML qui sera le point d’entrée de notre application index.html dans laquelle on ajoute, d’une part les librairies ne faisant pas partie des modules déclarés dans systemjs, puis la configuration systemjs.config.js que nous avons précédemment créée, et pour terminer un petit script pour lancer l’application.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ShowTheque Angular 2</title>
</head>
<body>
<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/reflect-metadata/Reflect.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>
</body>
</html>
Configuration de TypeScript
Pour la configuration de TypeScript, nous allons encore une fois nous inspirer de la documentation d’Angular pour créer notre tsconfig.json. J’y apporte plusieurs modifications, notamment l’ajout d’une propriété outDir car je mettrais les sources de l’application dans un répertoire src et les fichiers compilés dans un répertoire app.
{
"compilerOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false,
"outDir": "app"
},
"exclude": [
"node_modules"
]
}
Pour terminer, nous allons installer un fichier de définition de type pour la librairie core-js afin que TypeScript soit capable de compiler nos futures sources. Pour cela, nous utilisons l’outil typings précédemment installé, qui fonctionne un peu comme NPM. Il va créer un fichier typings.json contenant la liste des dépendances. Elles se téléchargent dans un répertoire typings (équivalent du node_modules).
$> npm run typings install dt~core-js -- --global --save
L'argument install car nous installons une dépendance. dt représente la source, ici le répertoire classique DefinitelyTyped puis le nom du type recherché.
Création du premier composant
Maintenant que tout est prêt, créons notre premier composant afin d’afficher une première page fonctionnant avec Angular 2. Pour ceux qui pratique déjà AngularJS 1 les controller n’existent plus, ils sont remplacés par des component. Pour créer un component, nous devons créer une classe et la décorer avec l’attribut @Component.
// src/app.component.ts
import { Component } from '@angular/core';
@Component({
selector:'app',
templateUrl: './app/app.component.html'
})
export class AppComponent
{
}
Ic, on importe l’objet Component depuis Angular et on décore la class avec. Dans ce décorateur on utilise deux propriétés :
- selector correspond à la balise HTML à utiliser dans notre page pour appeler ce composant
- templateUrl lien vers le HTML associé à notre composant
Créons de suite ce fichier, qui pour le moment contiendra simplement un titre et un texte.
<!--src/app.component.html-->
<h1>Home</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam cumque beatae a doloribus? Doloribus vero aperiam, laboriosam ipsum, ut eum voluptatum ad. Nisi et, veniam doloremque minima maiores non ut tempore eligendi, modi possimus corporis odio dolor aliquam ducimus harum hic ullam aspernatur repellendus nemo praesentium temporibus natus architecto iusto?<p/>
Création du module principal
Pour utiliser le composant précédemment créé, nous devons au préalable, créer un module. Les modules permettent de décomposer une application en plusieurs parties indépendantes. Il doit également y avoir un module principal qui fait appel à ces sous-modules. Créons le module central de notre application qui utilisera le composant AppComponent.
// src/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [BrowserModule],
declarations: [AppComponent],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Un module est une simple classe décorée avec @NgModule. Dans ce décorateur il y a 4 propriétés principales:
- imports c’est ici que nous mettons les modules Angular utilisés par notre application ainsi que nos propres modules. Pour faire fonctionner l’application nous devons au minimum inclure BrowserModule
- declarations ici nous mettrons les composants globaux de notre application; cela peut être par exemple des components ou des pipes
- providers ici nous mettrons les services injectables dans nos composants
- boostrap le composant de démarrage pour notre application
Lancement de l'application
Il ne reste plus que deux étapes. Tout d’abord, placer notre composant central dans notre page index.html; pour cela nous plaçons une balise correspondant à la propriété selector
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ShowTheque Angular 2</title>
</head>
<body>
<app>loading...</app>
<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/reflect-metadata/Reflect.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>
</body>
</html>
Puis, nous créons un fichier qui lancera notre application; il sera appelé par SystemJS, c’est le main.js dont nous avons parlé au début.
// src/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
Démarrage
Ne reste plus qu'a compiler le TypeScript et lancer l'application avec NPM:
$> npm run tsc
$> npm run server
C’est terminé pour cette première étape. Nous mettrons en place dans la prochaine leçon, Gulp, afin de compiler automatiquement nos sources et rafraichir le navigateur à chaque modification. Nous ajouterons également les librairies de style.