---
# System prepended metadata

title: Projet Angular Developer Friendly

---

# Projet Angular Developer Friendly
*Auteur: Gaëtan Rouziès*

Voici mes conseils pour mettre en place un projet Angular simple à comprendre et à developper.

Ce projet Angular optimise le bien être et la productivité du développeur et favorise une compréhension rapide pour tous les nouveaux developpeurs qui entreront sur le projet.

## Général
- Angular 8 (Prendre la dernière version au moment de la création du projet)
- Typescript
- Angular-cli pour la génération de composant/service
- Pour le versionning: Git avec le git-flow
- IDE: VSCode ou IntelliJ IDEA

## Arborescence
* app/
    * core/ (socle technique si besoin)
    * styles/
    * utils/
    * models/
    * components/
    * directives/
    * pipes/
    * services/
    * modules/
* assets/
* environments/

## Spécificités

### Général
- Utiliser une librairie CSS Populaire (Bootstrap, Material, etc.)
    - Cela peut être impossible suivant le contexte du projet suivant votre équipe UX/UI.
    - Vous pouvez demander à votre équipe UX/UI d'utiliser les classes générées par des packages externes afin que vous puissiez utiliser ces packages très utiles et populaires.
- Pas de mock back dans le code Angular, si un mock est nécessaire suivant le besoin du projet, celui-ci doit être dans un projet à part.
- Un seul fichier i18n par langue (fr.json, eng.json) et utilisation du package ``ngx-translate``
- Ne pas utiliser le type ``any`` en dehors des modèles et des réponses d'API
- Styles en SCSS ou LESS dans un dossier styles
- **Limiter grandement la création de composants génériques**
- **Priviligier l'utilisation de packages externes, ceux-ci doivent être populaire et fournir une documentation complète**

### Angular
- Un seul fichier contenant les routes *(A diviser, si le lazyloading est mis en place)*
- Un seul module pour les components (AppModule) *(A diviser, si le lazyloading est mis en place)*
- Les composants peuvent communiquer ensemble via des Input()/Output() ou des ``SharedService`` selon le besoin
- Pas de fichiers styles liés aux composants
- Création d'un module ``SharedModule`` qui contient tous les composants/modules utilisés dans l'ensemble de l'application (Translate, Pipes, etc.)
- Création d'un ``AppSharedModule`` et d'un ``TestingSharedModule`` qui import le ``SharedModule``
    - Le ``TestingSharedModule`` contiendra des modules uniquement nécessaire lors des tests (``RouterTestingModule``, ``HttpClientTestingModule``)
    - Le ``AppSharedModule`` contiendra des modules qui ne doivent pas être importés lors des tests (``RouterModule``, ``HttpClientModule``)


### Testing
- Tests exécutés avec un Chrome Headless (Ne pas utiliser PhantomJS)
- Utilisation de ``karma-spec-reporter`` pour le détail de l'exécution des tests et de ``karma-coverage-istanbul-reporter`` pour la couverture de code
- Les fichiers tests ne doivent pas importer de module de composants propres à l'application autre que le ``TestingSharedModule``


## Packages très importants
Ces packages ont un impact énorme sur la simplicité de développement et la productivité.
- ``ngx-translate``
- ``ts-cacheable``
- ``ngx-bootstrap`` (Modal, Dropdown, Pagination, Tooltip, Tab, Alert, ProgressBar)
    - C'est l'avantage d'utiliser une librairie CSS Populaire

## Scripts
Nous avons ajouté deux scripts
- ``npm run precommit``: Exécute le linter, le build en mode prod et les tests.
    - Utilisé très fréquemment par l'équipe de développeur, cela nous permets de rarement casser la branche develop
- ``npm run analyse``: Fournit le détail du bundle.js
    - Utilisé rarement mais utile à chaque ajout d'un package externe


## Spécificités en détails

### Déclaration des modèles

Les classes correspondantes à des données provenant d'API ont un constructor avec un paramètre data optionel de type ``any``.

```typescript
export class MyClass {

  field1: string;
  field2: string;
  field3: string;

  constructor(data?: any) {
    if (!data) {
      return;
    }
    this.field1 = data.field1;
    this.field2 = data.field2;
    this.field3 = data.field3;
  }
}
```