Typescript - Modul importieren, falls vorhanden
Wie importiert man ein Modul, wenn es existiert?
Ich habe 2 Projekte, Client & Server. Beide importieren dieselbe Datei.
Die Datei importiert ein Node-Modul, das nur im Serverprojekt installiert ist. Der Client hat das Modul nicht.
Also muss require das Modul typisiert zurückgeben, wenn es vom Serverprojekt aus geöffnet wird.
Und es muss undefined zurückgeben, wenn es vom Clientprojekt aus geöffnet wird.
Unten ein Screenshot vom Kundenprojekt. Typescript kompiliert nicht, weil es sagt, dass es das Modul nicht finden kann.
Ein einfaches require behält den Typ nicht bei:
Antwort #1
Es gibt 2 Teile davon:
- Eine formelle Importanweisung muss unbedingt bedingungslos sein.
importbedeutet, dass das Modul immer existieren muss. Das bedeutet nicht, dass es das Modul sein muss, das Sie tatsächlich benötigen. - Der gewünschte Typ ist
module | undefinedauf der Serverseite. Aber auf der Clientseite istmoduleunbekannt. Um also serverbasierte Aufrufe zu ermöglichen, sollten beliebige Felder verwendet werden dürfen, wie{[k:string]:any}, und wir müssen in der Lage sein zu wählen, welches für die Seite, auf der wir uns befinden, geeignet ist.
Ihre beste Option ist wahrscheinlich, ein leeres Modul mit demselben Namen auf Ihrer Client-Seite hinzuzufügen, also eine Datei namens type-graphql.ts im node_modules-Ordner auf der Client-Seite, die nur Folgendes enthält:
export {}
Auf diese Weise wird der bedingungslose Import immer funktionieren: Der Client wird diese leere Moduld Datei importieren und der Server wird die eigentliche Bibliothek importieren. Dann müssen Sie nur die Variable neu zuweisen, um mögliche Schnittstellen zu berücksichtigen:
import * as _TypeGraphQL from 'type-graphql';
// don't check methods on the client side, if we had type definitions on both we could just use that
type CLIENT_SIDE_INTERFACE = {[k:string]:any};
// on server side we can check for case that the module is not present.
type SERVER_SIDE_INTERFACE = typeof _TypeGraphQL | {"ISDUMMY":true}
// if the imported module has our indicator key then we are on the client side
type THIS_SIDE_INTERFACE = "ISDUMMY" extends (keyof typeof _TypeGraphQL) ? CLIENT_SIDE_INTERFACE : SERVER_SIDE_INTERFACE
const TypeGraphQL: THIS_SIDE_INTERFACE = _TypeGraphQL;
Nachdem mir aufgezeigt wurde, dass das Ablegen von Dateien im normalen node_modules-Ordner problematisch ist, kann ich auch eine mögliche Lösung dafür anbieten.
Node löst Module (die nicht mit ./ oder / beginnen) auf, indem es den Ordnerbaum von der aktuellen Datei aus nach oben durchläuft und auf jeder Ebene prüft, ob es einen Ordner namens node_modules gibt. Normalerweise bedeutet dies, dass es im Stammverzeichnis Ihres Projekts einen Ordner gibt, der alle Module enthält. Sie können jedoch in der Mitte Ihres Projekts einen weiteren Ordner namens node_modules hinzufügen, und alle Importe von Dateien dort durchsuchen diesen Ordner zuerst.
Also würde eine Ordnerstruktur wie diese es ermöglichen, die Dummy-Datei im Projekt so zu platzieren, dass import * as a from 'test-graphql' aus einem stabilen Ordner importiert wird:
root
- node_modules
- src
--- SUBFOLDERS
- node_modules
-test-graphql.tsx (dummy code)
- git-sub-module
- wrapper.tsx (containing the import code mentioned above)
Der Code in der wrapper.tsx würde in diesem Fall versuchen, aus den inneren node_modules zu importieren und die leere Moduldatei zu importieren. Stellen Sie einfach sicher, dass Sie ausreichende Kommentare in dem leeren Modul hinzufügen, die erklären, welche Zauberei hier vor sich geht :)

