Appearance
Créer une librairie Angular
Pourquoi créer une librairie ?
Imaginez une boîte à outils que vous pourriez partager avec vos collègues ou d'autres développeurs. C'est exactement ce qu'est une librairie Angular. Voici quelques raisons pour lesquelles vous pourriez vouloir créer une librairie :
Réutilisation du code : Au lieu de réécrire les mêmes composants ou services dans chaque projet, vous pouvez les centraliser dans une librairie et les réutiliser facilement.
Maintenance simplifiée : Les mises à jour et les corrections de bugs peuvent être effectuées à un seul endroit, puis propagées à tous les projets utilisant la librairie.
Cohérence : Une librairie permet d'assurer une cohérence visuelle et fonctionnelle entre différents projets, particulièrement utile pour les grandes organisations.
Collaboration : Les librairies facilitent le partage de code entre équipes ou avec la communauté open-source.
Modularité : Vous pouvez diviser votre application en modules plus petits et plus gérables, chacun pouvant être développé et testé indépendamment.
Optimisation des performances : Les librairies bien conçues peuvent être optimisées pour la taille du bundle et les performances, bénéficiant à tous les projets qui les utilisent.
EXEMPLE CONCRET
Imaginons que vous travaillez sur plusieurs projets Angular qui nécessitent tous une gestion des utilisateurs. Au lieu de recréer les composants de carte utilisateur, de liste d'utilisateurs, et les services associés dans chaque projet, vous pourriez les regrouper dans une librairie my-user-lib
. Cette approche vous fera gagner du temps, réduira les duplications de code et assurera une expérience utilisateur cohérente à travers vos applications.
Création de la librairie
1. Générer la librairie
Commençons par créer une nouvelle librairie avec la CLI Angular :
bash
ng new my-workspace --no-create-application
cd my-workspace
ng generate library my-user-lib
Nom de la librairie
Choisissez un nom explicite pour votre librairie qui décrit bien sa fonction. D'après la documentation officielle, le nom de la librairie devrait éviter de commencer par ng-
car c'est un préfixe réservé pour les librairies officielles d'Angular.
Ajouter une application
Si vous souhaitez créer une application qui utilise votre librairie, vous pouvez en ajouter une avec la commande ng generate application my-app
.
2. Structure du projet
Après la génération, vous aurez une structure comme celle-ci :
my-workspace/
├── projects/
│ └── my-user-lib/
│ ├── src/
│ │ ├── lib/
│ │ ├── public-api.ts
│ │ └── test.ts
│ ├── ng-package.json
│ ├── package.json
│ └── tsconfig.lib.json
└── package.json
3. Création d'un composant
Créons un composant réutilisable pour notre librairie :
ts
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { User } from './user.interface';
@Component({
selector: 'lib-user-card',
standalone: true,
imports: [CommonModule],
template: `
@if (user) {
<div class="user-card">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
}
`,
styles: `
.user-card {
padding: 1rem;
border: 1px solid #ccc;
border-radius: 4px;
}
`
})
export class UserCardComponent {
@Input() user: User | undefined;
}
ts
export interface User {
id: number;
name: string;
username: string;
email: string;
}
4. Export des composants
Pour rendre votre composant accessible, vous devez l'exporter dans le public-api.ts
:
ts
export * from './lib/user-card/user-card.component';
export * from './lib/user-card/user.interface';
5. Ajouter des dépendances (optionnel)
Si votre librairie nécessite des dépendances externes, vous pouvez les spécifier dans le fichier package.json
de votre librairie. Voici un exemple de structure pour le package.json
(ici avec lodash
en dépendance) :
json
{
"name": "my-user-lib",
"version": "1.0.0",
"peerDependencies": {
"@angular/common": ">=17.0.0",
"@angular/core": ">=17.0.0"
},
"dependencies": {
"tslib": "^2.3.0",
"lodash": "^4.17.21"
},
"sideEffects": false,
"license": "MIT",
"author": "Votre Nom",
"repository": "https://github.com/votre-username/my-user-lib",
"publishConfig": {
"access": "public"
}
}
json
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/my-user-lib",
"lib": {
"entryFile": "src/public-api.ts"
},
"allowedNonPeerDependencies": [
"lodash"
]
}
Expliquons chaque section :
- Les
peerDependencies
sont les dépendances que votre librairie s'attend à trouver dans le projet hôte. Typiquement, il s'agit des packages Angular core.
CONSEIL
Utilisez >=
pour la version d'Angular pour permettre la compatibilité avec les versions futures, tant que votre librairie reste compatible.
- Les
dependencies
sont les packages externes dont votre librairie a besoin pour fonctionner. Ces dépendances seront installées automatiquement avec votre librairie.
ATTENTION
Il faut penser à ajouter allowedNonPeerDependencies
dans le ng-package.json
si vous utilisez des dépendances qui ne sont pas des peerDependencies. De plus, si vous tester votre librairie en développement, il faut penser à ajouter la dépendance à la racine du projet avec npm install <nom-de-la-dependance>
.
6. Build et publication
Pour construire votre librairie :
bash
ng build my-user-lib
ATTENTION
Assurez-vous de mettre à jour la version dans le package.json
de votre librairie avant chaque publication.
Pour publier sur npm :
bash
cd dist/my-user-lib
npm publish
Utilisation de la librairie
Dans un projet Angular, vous pouvez maintenant installer et utiliser votre librairie :
bash
npm install my-user-lib
Tester en développement
Si vous souhaitez tester votre librairie en développement, vous n'êtes pas obligé de la publier sur npm. Vous pouvez directement l'utiliser dans votre code. Mais il faut penser à builder la librairie avant.
Vous pouvez builder en fond avec la commande ng build my-user-lib --watch
qui va reconstruire la librairie à chaque changement.
Exemple d'utilisation :
ts
import { Component } from '@angular/core';
import { UserCardComponent } from 'my-user-lib';
@Component({
selector: 'app-home',
standalone: true,
imports: [UserCardComponent],
template: `
<lib-user-card [user]="currentUser"></lib-user-card>
`
})
export class HomeComponent {
currentUser = {
id: 1,
name: 'John Doe',
username: 'johndoe',
email: '[email protected]'
};
}