Eine Angular Library schreiben
Tags: angular, typescript, npm, german
Published: 2019-12-01 12:40:12

Es kommt vor, dass man Code für eine Angular Anwendung schreibt, den man eigentlich in mehreren Projekten benötigt.
Anstatt den Code zu kopieren und somit gegen das [DRY Prinzip](https://de.wikipedia.org/wiki/Don%E2%80%99t_repeat_yourself) zu verstoßen, ist es sinnvoll, den Code zu isolieren und als eigene [Angular Library](https://angular.io/guide/creating-libraries) zu veröffentlichen.

<hr>

## Neues Projekt anlegen
Um die Library entwickeln zu können, müssen wir zuerst ein neues Angular Projekt bzw. einen Workspace anlegen.

Workspaces unterscheiden sich von "normalen" Angular Anwendungen darin, dass es kein einzelnes Projekt gibt, sondern einen Arbeitsbereich hat, in dem man mehrere Projekte hinzufügen kann.

Wir brauchen somit:
1. ein Library Projekt in welchem wir den Code, den wir isolieren wollen, schreiben und
2. eine Angular Anwendung, mit welcher wir die Library testen können.

Legen wir als erstes einmal den Workspace an. Ich möchte in meinem konkreten Fall einen Form Generator schreiben. Durch die Option `--create-application=false` wird ein Workspace anstatt einem Projekt erzeugt

```bash
$ ng new form-builder --create-application=false

Would you like to add Angular routing? No
Which stylesheet format would you like to use? CSS

CREATE form-builder/README.md (1028 bytes)
CREATE form-builder/.editorconfig (246 bytes)
CREATE form-builder/.gitignore (629 bytes)
CREATE form-builder/angular.json (135 bytes)
CREATE form-builder/package.json (1263 bytes)
CREATE form-builder/tsconfig.json (435 bytes)
CREATE form-builder/tslint.json (1621 bytes)

// ...
``` 

Als nächstes wechseln wir in das Workspace Verzeichnis und legen das Library Projekt und die Beispiel Anwendung an
```bash
$ cd form-builder
$ ng g library form-builder
$ ng g application form-builder-example
```

Im Verzeichnis `projects` sollten bei dir nun 3 Projekte liegen. Einmal das Library Projekt, dann die Angular Anwendung und dann noch die e2e Tests der Angular Anwendung.

```
projects/
|- form-builder
|- form-builder-example/
|- form-builder-example-e2e/
```

Das Library Projekt hat einen Ordner `src/lib`. In diesem befindet sich der Code deiner Library. Außerdem existiert eine Datei `src/public-api.ts`. In dieser musst du alles hinterlegen, was du aus deiner Library für andere Anwendungen verfügbar machen möchtest. Das können z.B. Komponenten oder Services sein.

## Build Script
Als nächstes musst du in der Workspace übergreifenden `package.json` zwei neue Scripts hinzufügen.
```json
{
  "scripts": {
    // ...
    "lib:build": "ng build form-builder",
    "lib:dev": "ng build form-builder --watch"
  }
}
```

`lib:build` dient zum bauen der Library und `lib:dev` zum ausführen des build Prozess während der Entwicklungszeit.

Führe zunächst einmal `npm run lib:build` aus, um die Library einmal initial zu bauen.


## Library einbinden
Um nun deine Library in der Example Anwendung verwenden zu können, musst du in der Example Anwendung im AppModule (`projects/form-builder-example/src/app/app.module.ts`) im `@NgModule` Decorator unter imports die Library importieren.
Wichtig: wir wollen die gebaute Version verwenden, deshalb achte darauf, dass du die richtige Datei aus dem `dist/` Verzeichnis importierst.

```typescript
// projects/form-builder-example/src/app/app.module.ts

// ...

import {FormBuilderModule} from '../../../../dist/form-builder'; // <--

@NgModule({
  // ...
  imports: [
    // ...
    FormBuilderModule, // <--
  ],
  // ...
})
export class AppModule {
}
```

Nun kannst du in einer Kommandozeile `ng serve` und in einer zweiten `npm run lib:dev` ausführen.

Unter [http://localhost:4200](http://localhost:4200) kannst du deine Testanwendung aufrufen.

## Library verwenden
Du kannst nun wie gewohnt im Verzeichnis deiner Example Anwendung den Code aus der Library verwenden. In meinem konkreten Fall habe ich z.B. im `app.component.html` einfach die `<form-builder>` Komponente eingebunden.

## Zusammenfassung
Du weißt nun was ein Angular Workspace ist und kannst einen solchen anlegen. Außerdem weißt du nun, wie du ein Library Projekt anlegst und in einer example Anwendung einbindest und testen kannst.

Zum veröffentlichen der Library im NPM Repository, kannst du dir am besten die [Dokumentation](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry) anschauen.


Danke für's lesen und ich hoffe ich konnte alles verständlich rüberbringen.

Fragen und Anregungen gerne in die Kommentare🙂