Partir du début
Si la mémoire me sert bien, alors à partir de la version 6 en angulaire, il est devenu possible de créer différents types de projets dans un seul espace de travail: application et bibliothèque.
Jusqu'à ce point, les gens qui voulaient créer une bibliothèque de composants utilisaient très probablement l'excellent et utile package ng-packagr, qui aidait à créer le package dans le format accepté pour angular. En fait, j'ai créé la bibliothèque précédente en utilisant cet outil. Maintenant, l'équipe angulaire a inclus ng-packagr dans angular-cli et a ajouté des schémas pour créer et construire des bibliothèques, a étendu le format angular.json et ajouté quelques autres commodités. Passons maintenant de ng new à npm install - de la création d'une bibliothèque vide à sa publication et son importation dans un projet tiers.
L'espace de travail est créé comme d'habitude
ng new test-app
L'espace de travail et le projet d'application seront créés, jetez un œil à angular.json
{ ... "projects": { "test-app": { ... "sourceRoot": "src", "projectType": "application", "prefix": "app" ... } ... } ... }
Maintenant, ajoutez le projet de bibliothèque
ng generate library test-lib --prefix=tl
nous ajouterons la clé --prefix pour indiquer que les composants et les directives utiliseront le préfixe tl, c'est-à-dire que les balises des composants ressembleront à
<tl-component-name></tl-component-name>
Voyons maintenant dans angular.json, nous avons ajouté un nouveau projet
{ ... "projects": { "test-app": { "root": "", "sourceRoot": "src", "projectType": "application", "prefix": "app" ... }, ... "test-lib": { "root": "projects/test-lib", "sourceRoot": "projects/test-lib/src", "projectType": "library", "prefix": "tl" } ... } ... }
La structure suivante est apparue dans le répertoire du projet
- projects - test-lib ng-package.json package.json - src public-api.ts - lib test-lib.component.ts test-lib.module.ts test-lib.service.ts
De plus, dans tsconfig.json, il y a un ajout dans la section des chemins
"paths": { "test-lib": [ "dist/test-lib" ], "test-lib/*": [ "dist/test-lib/*" ] }
Maintenant, si vous exécutez l'application,
ng serve
alors nous verrons un modèle d'application angulaire de travail standard
Création de fonctionnalités de bibliothèque
Créons une bibliothèque avec un service, une directive et un composant. Nous placerons le service et la directive dans différents modules. Passons au répertoire projects / test-lib / src / lib et supprimons test-lib. *. Ts, supprimons également le contenu de projects / test-lib / src / public-api.ts.
Passons à projets / test-lib / src / lib et créons des modules, directive, service et composant
ng g module list ng g module border ng g service list /* list*/ ng g component list /* border*/ ng g directive border
Remplissez le composant, le service et la directive de logique. Le composant affichera une liste des lignes soumises à l'entrée. La directive est d'ajouter un cadre rouge, le service ajoutera l'horodatage actuel à l'Observable chaque seconde.
Le service
import {Injectable} from '@angular/core'; import {Observable, Subject} from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ListService { timer: any; private list$: Subject<string> = new Subject<string>(); list: Observable<string> = this.list$.asObservable(); constructor() { this.timer = setInterval(this.nextItem.bind(this), 1000); } nextItem() { const now = new Date(); const currentTime = now.getTime().toString(); this.list$.next(currentTime); } }
Liste des composants et module
import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {ListComponent} from './list/list.component'; @NgModule({ declarations: [ ListComponent ], exports: [ ListComponent ], imports: [ CommonModule ] }) export class ListModule { } @Component({ selector: 'tl-list', template: ` <ul> <li *ngFor="let item of list">{{item}}</li> </ul>`, styleUrls: ['./list.component.css'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ListComponent implements OnInit { @Input() list: string[]; constructor() { } ngOnInit() { } }
Cadre
import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {BorderDirective} from './border.directive'; @NgModule({ declarations: [ BorderDirective ], exports: [ BorderDirective ], imports: [ CommonModule ] }) export class BorderModule { } import {Directive, ElementRef, OnInit} from '@angular/core'; @Directive({ selector: '[tlBorder]' }) export class BorderDirective implements OnInit { private element$: HTMLElement; constructor(private elementRef$: ElementRef) { this.element$ = elementRef$.nativeElement; } ngOnInit() { this.element$.style.border = 'solid 1px red'; } }
! C'est important. Lors de la génération de composants et de bibliothèques, cli ne crée pas d'exportation, assurez-vous donc d'ajouter les composants et les directives qui devraient être disponibles dans la section d'exportation des modules.
De plus, afin que dans le futur des classes de la bibliothèque soient disponibles, nous ajouterons du code à public-api.ts
export * from './lib/list.service'; export * from './lib/border/border.module'; export * from './lib/border/border.directive'; export * from './lib/list/list.module'; export * from './lib/list/list/list.component';
Connexion d'une bibliothèque dans une application de test
Assemblons le projet de bibliothèque
ng build test-lib --watch
Ensuite, dans app.module, nous importerons les modules avec le composant et la directive et ajouterons la logique
import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; import {AppRoutingModule} from './app-routing.module'; import {AppComponent} from './app.component'; import {ListModule} from 'test-lib'; import {BorderModule} from 'test-lib'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, ListModule, BorderModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Et utilisez les morceaux de notre bibliothèque dans l'application
import {Component, OnInit} from '@angular/core'; import {ListService} from 'test-lib'; @Component({ selector: 'app-root', template: ` <tl-list [list]="list"></tl-list> <div tlBorder>I am bordered now</div>`, styleUrls: ['./app.component.styl'] }) export class AppComponent implements OnInit { list: string[] = []; constructor(private svc$: ListService) { } ngOnInit() { this.svc$.list.subscribe((value => this.list = [...this.list, value])); } }
Exécutez et vérifiez l'application, tout fonctionne:

Assemblage et publication
Reste à collecter et publier le package. Pour l'assemblage et la publication, il est pratique d'ajouter des commandes aux scripts dans l'application package.json
{ "name": "test-app", "version": "0.0.1", "scripts": { ... "lib:build": "ng build test-lib", "lib:watch": "ng build test-lib --watch", "lib:publish": "npm run lib:build && cd dist/test-lib && npm pack npm publish", ... } }
La bibliothèque est compilée, publiée, maintenant après l'installation dans tout autre projet angulaire
npm install test-lib
Vous pouvez utiliser des composants et des directives.
Petite note
Nous avons toute une famille de packages npm dans notre entreprise, donc dans notre cas, le package doit être publié avec un espace de noms en tant que
company / test-lib. Pour ce faire, nous allons simplement apporter quelques modifications
Renommez le package dans la bibliothèque package.json
/* projects/test-lib/package.json */ { "name": "@company/test-lib", "version": "0.0.1", "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0" } }
Et pour que dans l'application de test la bibliothèque soit accessible par son nom avec un espace de noms, nous allons corriger un peu tsconfig
/* test-app/tsconfig.json */ *** "paths": { "@company/test-lib": [ "dist/test-lib" ], "@company/test-lib/*": [ "dist/test-lib/*" ] } ***
Et dans l'application de test, remplacez les importations, par exemple
import {ListModule} from 'test-lib';
Remplacez par
import {ListModule} from '@company/test-lib';
C'est la fin.
PS: Quand j'ai étudié ce sujet, j'ai lu une fois les articles suivants
La série des bibliothèques angulairesComment créer une bibliothèque de composants prêts pour npm avec Angular