Jun 24, 2021
Der schwierigste und mühsamste Teil beim Start eines neuen Projekts war schon immer die Einrichtung der Anfangsstruktur. Die Ersteinrichtung nimmt viel Zeit in Anspruch und die meisten Dinge sind bei den meisten Projekten mehr oder weniger gleich.
Nehmen wir an, wir haben eine Anwendung, die entwickelt werden muss und eine Benutzerverwaltung (Rollen, Authentifizierung), ein Dashboard/eine Landing Page, die einige Daten/Ressourcen anzeigt, vielleicht Übersetzungen für die Unterstützung mehrerer Sprachen und vieles mehr enthalten soll.
Warum all das von Grund auf neu entwickeln, wenn wir eine Vorlage erstellen können, die wir nach unseren Bedürfnissen weiter anpassen können?
Um diese Frage zu beantworten, sind wir auf die Idee gekommen, eine Kernvorlage zu haben. Und so wurde Firestarter geboren. Firestarter ist eine Monorepo-Vorlage, die NestJS für das Backend, React (mit Material-UI) für das Frontend und MongoDB als Datenbank verwendet. Es soll die Starthilfe sein, die jedes Projekt braucht. Es kommt mit allen grundlegenden Dingen, die wir brauchen, wie Benutzerauthentifizierung und -verwaltung, Medienupload und -verwaltung, Auditing und mehr.
Firestarter ist nicht nur eine gewöhnliche Vorlage, sondern verfügt über einen Generator für vollständige Routen (Backend und Frontend) oder nur Endpunkte mit Paginierung, Gebietsschema und Arbeitsbereich. Dazu verwendet es hygen, einen skalierbaren Codegenerator, mit dem wir Vorlagen in EJS schreiben und unsere eigenen Generatoren erstellen können, was immer hilfreich ist.
Um einen neuen API-Endpunkt zu erzeugen, müssen wir nur den folgenden Befehl ausführen:
hygen api new
Nach der Ausführung werden Sie aufgefordert, zusätzliche Informationen wie den Namen der Entität, die mit dem Endpunkt verknüpft ist, die Felder der Entität und die optionalen Funktionen, die wir verwenden möchten, wie z. B. Paginierung und Locales, anzugeben. Nach erfolgreichem Abschluss wird ein neues Modul erstellt und in das App-Modul importiert.
Es gibt einen weiteren Befehl, um eine Seite mit einer Front-End-Route und einem Back-End-Endpunkt unter Verwendung eines von uns definierten Modells zu erzeugen:
hygen page new
Wie bereits erwähnt, fragt dieser Befehl nach dem Namen der zugehörigen Entität, den Feldern der Entität und den optionalen Merkmalen. Danach wird der grundlegende Code generiert, damit wir loslegen können.
Wenn wir einen Generator definieren wollen, müssen wir eine bestimmte Ordnerstruktur im Ordner _templates im Stammverzeichnis des Projekts erstellen. Die Ordnerstruktur entspricht dem Befehl, den wir eingeben, wenn wir etwas generieren wollen.
Wenn der Befehl zum Beispiel lauten soll:
hygen api new
muss die Ordnerstruktur wie folgt aussehen:
_templates └── api └── new
Der Generator besteht aus mehreren Vorlagen. Jede Vorlage entspricht einer Datei, die erstellt wird. Die Vorlagen verwenden EJS und bestehen aus zwei Teilen:
Hier ist ein Beispiel für eine Vorlage:
--- to: src/app.module.ts inject: true skip: 'import { <%= name %>Module } from' after: '// import line - do not remove or edit' --- import { <%= name %>Module } from './<%= h.changeCase.headerCase(name) %>/<%= h.changeCase.headerCase(name) %>.module';
Wir sehen, dass der Header mit drei Bindestrichen (-) getrennt ist und eine Reihe von Parametern definiert. Die Parameter dienen als Regeln für den Generator bei der Generierung des Codes. Der to-Parameter legt beispielsweise das Ziel der Datei fest, der after-Parameter definiert, wo der Body in dieser Datei platziert werden soll, falls sie existiert, und so weiter. Außerdem können wir eine Eingabeaufforderung definieren, die vor der Generierung eine Benutzereingabe verlangt. Dies kann verwendet werden, um der Entität, die wir erstellen, einen Namen zu geben oder eine Art von Struktur zu definieren. Die Eingabeaufforderung wird in einer Datei namens prompt.js im selben Ordner wie die Vorlagen definiert.
Hier ist ein Beispiel für einen Prompt:
module.exports = [ { type: "input", name: "name", message: "Geben Sie einen neuen Entitätsnamen ein:" }, { type: "list", name: "model", message: "Bitte geben Sie ein Datenmodell ein:" }, { type: "multiselect", name: "plugins", message: "Select plugins", choices: [ { name: "locales", message: "Locales", value: "locales" }, { name: "paginate", message: "Pagination", value: "paginieren" } ] } ];
Wie im obigen Beispiel beschrieben, können wir Eingaben verschiedener Typen definieren. Im Beispiel haben wir drei verschiedene Eingaben definiert, die uns in der Vorlage als Eigenschaft mit dem hier angegebenen Wertnamen zur Verfügung stehen werden. Die erste ist eine normale Texteingabe, die ein String sein wird, die zweite ist eine Liste, die zu einem Array wird (muss mit**,** getrennt werden) und die dritte ist ein 'multi select', das ein Array mit den Namen der von uns ausgewählten Elemente zurückgeben wird.
Die Backend-Anwendung verwendet NestJS, Mongoose ODM und MongoDB und das Frontend verwendet React, das mit TypeScript eingerichtet wurde.
Andere Technologien, die wir verwenden, sind die folgenden:
Das Template bietet viele Funktionen, die sofort einsatzbereit sind, wie z. B:
Das Backend verwendet NestJS und folgt der Philosophie des Frameworks. Die Architektur ist stark von Angular inspiriert. Die Organisation unseres Codes in verschiedene funktionale Module hilft bei der Entwicklung komplexer Anwendungen und ermöglicht die Wiederverwendbarkeit. Module kapseln die gesamte Logik für einen bestimmten Bereich.
Nehmen wir an, wir müssen eine benutzerbezogene Logik implementieren. Wir können ein UserModule erstellen, das UserService, UserController und ein UserSchema enthält. Wir können auch die Tatsache ausnutzen, dass wir TypeScript verwenden, indem wir ein DTO und eine Klasse dafür erstellen, die wir später für eine strenge Typüberprüfung verwenden können. Am Ende hat jede Entität, die eine bestimmte Domäne abdeckt, ihr eigenes Modul mit der folgenden Struktur:
user ├── classes │ └── user.class.ts ├── dto │ └── user.dto.ts ├── user.module.ts ├── user.controller.ts ├── user.service.ts └── user.schema.ts
Aufbau des Frontends
Das Frontend verwendet React. Die Anwendung ist wie folgt aufgebaut:
src ├── components │ └── Navbar │ ├── Navbar.scss │ └── Navbar.tsx ├── containers │ └── User │ ├── UserTypes.ts │ ├── UserActions.ts │ ├── UserReducer.ts │ ├── User.tsx │ ├── UserView.tsx │ └── User.scss ├── layouts │ └── AdminLayout │ ├── AdminLayout.scss │ └─ ─ AdminLayout.tsx ├── routes │ └── AdminRoutes.ts ├── repository │ └── user.ts ├── services │ └── permissions.ts ├── theme │ ├── main.scss │ └── theme.ts ├── reducers.ts ├── store.ts └── index.tsx
Nun werden wir uns mit der Struktur befassen, die alle im vorherigen Baum aufgeführten Funktionen enthält:

Zusammenfassung
Der Kunde möchte, dass das Produkt in kürzester Zeit mit den von ihm gewünschten Funktionen entwickelt wird. Mit dieser Anwendung können wir ein Produkt viel schneller liefern, da wir das Rad nicht jedes Mal neu erfinden müssen, wenn wir ein neues Projekt beginnen.

Tanja Zlatanovska
Vertrauen bei führenden Unternehmen weltweit




Intertec


Aneta Pejchinoska


Intertec