Angular 2 – Structure d’un projet

de | décembre 29, 2016

Angular2 est sorti depuis quelques mois maintenant. J’ai eu l’occasion de travailler sur un projet dès sa sortie. Je suis maintenant à même de commencer une petite série de tutoriaux sur les points qui me semblent les plus importants ou qui m’ont posés le plus d’interrogation.

Contrairement à la série sur EmberJS, qu’il faut que je finisse d?ailleurs :), je vais ici faire une suite d’article sur des sujets particuliers plutôt qu’un projet de A à Z. Cela s?avérera moins chronophage. Je pars du principe que vous êtes capable de lire une documentation. Donc je ne paraphraserais pas la documentation d’Angular2.

Dans ce premier article, nous allons voir la structure d’un projet en profondeur avec la modularisation et les différents types de module. Alors c’est partie.

Angular2 et la modularité

La modularité dans un projet à longtemps été considérée comme une chimère. Angular2 propose ici une solution innovante avec des modules autonomes pouvant être réutilisés d’un projet à un autre, exportés sur npm, et chargés en différés (lazy-loading) par une application pour ne pas retarder son démarrage. C’est pour moi un des gros points fort d’Angular2 sur EmberJS.

Structure d’un projet Angular2

Avant tout, sachez qu’il existe une multitude de manière de structurer son projet. Pour ma part, j’ai choisi la structure recommandée par l’équipe d’Angular au travers leur projet Angular-cli. A la création d’un nouveau projet, on se retrouve avec une structure semblable à celle-ci :

Laissons de coté pour le moment les fichiers présents et intéressons-nous à la structure des répertoires. Le c?ur de notre application est le dossier src/app. C’est ce dossier qui contiendra tout le code de notre application.  src/assets contiendra toutes nos images et fichiers statiques. src/environnements contiendra la configuration de nos différents environnements ( Prod, Test, Dev, etc).

Les modules

Dans angular2, un module se déclare dans un fichier appeler nom_du_module.module.ts par convention. Un module est une classe annotée par @ngModule. Comme dit plus haut, un module doit être totalement autonome, c’est-à-dire qu’un simple import doit permettre de l’utiliser.

Angular2 recommande deux modules de base. J’en ai ajouté deux autres qui m’ont semblé indispensables.

  • Core : ce module contient tous éléments qui ne devront être instanciés qu’une fois dans la durée de vie de votre application. Ces éléments qui seront de facto considérés comme des singletons sont généralement des services gérant les accès au backend.
  • Shared : ce module contiendra tous les composants et directives génériques qui pourront être réutilisés dans d’autres projets.
  • Public : ce module contiendra toute la partie publique de votre application.
  • Private : ce module contiendra toute la partie privée/administration de votre application

SI votre application commence à grossir, vous pouvez créer un module pour chaque fonctionnalité de votre application. De cette manière vous avez la possibilité de charger en différé ces fonctionnalités lors de leurs accès par l’utilisateur.

Module Core

Comme vu précédemment, tous les éléments placés dans le module Core seront des singletons. Cela se prête donc particulièrement à des services ( http, session, …). Par contre des composants dont l’état dépend d’une requête http ne pourront pas se trouver dans ce module sous peine de mener à des comportements imprévisibles. Voyons maintenant comment faire en sorte que le Core module ne soit instancié qu’une seule fois.


@NgModule({
    providers: []
})
export class CoreModule {

    constructor( @Optional() @SkipSelf() parentModule: CoreModule) {
        if (parentModule) {
            throw new Error('CoreModule is already loaded. Import it in the AppModule only');
        }
    }
}

Dans le constructeur de celui-ci, Nous injectons notre CoreModule. L’annotation @SkipSelf() permet d’éviter les redondances cycliques. Ensuite on test s’il existe un parentModule. Ceci est impossible si le CoreModule est instancié par l’AppModule car il s’agit du module Racine. Avec cette manipulation, une exception se déclenchera si un développeur essaye d’injecter le CoreModule dans un autre module. Maintenant que nous savons comment n’instancier qu’une seule fois le CoreModule. Voyons comment nous l’instancions   dans l’AppModule.


// others imports

/* Core Module */
import { CoreModule } from './core/core.module';

/* Feature Module */
import { PublicModule } from './public/public.module';
import { PrivateModule } from './private/private.module';

@NgModule({
    declarations: [AppComponent],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        PrivateModule,
        PublicModule,
        CoreModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }

L’import du CoreModule se fait de la même manière que n’importe quels modules. J’ai d’ailleurs inclus aussi les PrivateModule et PublicModule de la même façon. Par contre notez que notre SharedModule lui n’est pas importé dans l’AppModule.

Shared Module

Le SharedModule est l’exact opposé sur CoreModule. C’est-à-dire que chaque élément(Services, Directives, Composants) exporté par celui-ci aura une nouvelle instance à chaque injection. Contrairement au CoreModule, Le SharedModule sera à importé directement dans les modules concernés (PublicModule, PrivateModule, …). De ce fait il ne devra contenir que des éléments génériques pouvant aussi bien service dans n’importe quel module où il est importé. Un bon exemple sont les composants d’affichage et de présentation des données, comme une datatable, une liste déroulante ou encore un carrousel. Les services ne trouveront que rarement leurs places dans ce composant car la plupart sont intimement liés à la session d’un utilisateur.

J’espère que cette première approche vous à plus. J’ai commencé par ce sujet parce que c’est ce qui m’a le plus posé problème au démarrage. La documentation de Angular2 n’étant pas très prolixe sur le sujet. De plus il s’agit d’un point fondamental à maitriser pour toutes applications prenant de l’envergure.

A bientôt.

00

Une réflexion au sujet de « Angular 2 – Structure d’un projet »

  1. Ping : Angular 2 ? Surcharger un service Angular – Le blog de Scandi

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.