Wie verwende ich npm-Module aus Typoskript?

87

Ich versuche es mit Typoskript. Es funktioniert gut auf der Hallo-Weltbühne. Ich versuche jetzt, ein npm-Modul zu verwenden:

index.ts =

import _ = require('lodash')

console.log(_.toUpper('Hello, world !'))

Das funktioniert nicht:

  • tsc index.ts -> Cannot find module 'lodash'. (2307)
  • node-ts index.js -> Cannot find module 'lodash'. (2307)

Ein Blick auf die Typoskript-Dokumentation und auf Google hat nicht geholfen. Andere S / O-Fragen sind entweder unbeantwortet ( hier und hier ) oder haben nichts damit zu tun.

Elemente:

  • Typoskript 1.8 spätestens
  • Ja, lodash ist installiert npm i --save lodashund in meinem Dateisystem vorhanden ( aktiviert )
  • Ich habe es auch getan typings i --save lodash
  • Varianten import * as _ from 'lodash'oder const _ = require('lodash')funktionieren auch nicht
  • Ich habe versucht, die Optionen von tsconfig.json zu optimieren, wie in anderen Antworten vorgeschlagen, "moduleResolution": "node"und "module": "commonjs"wie in einigen Antworten vorgeschlagen, funktioniert immer noch nicht

Wie verbrauchen wir ein npm-Paket in Typoskript?

Offirmo
quelle
2
Haben Sie in Ihrem index.ts einen Verweis auf lodash.d.ts hinzugefügt? Es sollte ///<reference path="../typings/lodash/lodash.d.ts"/>
ungefähr
@ Ranga Es funktioniert. Können Sie dies als Antwort hinzufügen?
Offirmo
2
Ich bin froh, dass es funktioniert. Blackus hat die Antwort bereits hinzugefügt und spezifiziert, was ich noch besser vorgeschlagen habe. Ein Hinweis: Wenn Eingabedateien in der Befehlszeile angegeben werden (was in Ihrem Fall der Fall ist), werden die Dateien tsconfig.json ignoriert. ( Quelle )
Granga

Antworten:

60

[EDIT] Vielen Dank für diese Antwort! Ab 2018 ist es jedoch veraltet. Leser, schauen Sie sich die anderen Antworten an.

Es gibt verschiedene Möglichkeiten, Module aus npm zu importieren. Wenn Sie jedoch keine Eingaben erhalten, tscwird sich immer beschweren, dass das gewünschte Modul nicht gefunden werden kann (auch wenn transpiled js tatsächlich funktioniert).

  • Wenn Sie über Typisierungen verfügen und keine verwenden tsconfig.json, referenceimportieren Sie die Typisierungen mit:

    /// <reference path="path/to/typings/typings.d.ts" />
    
    import * as _ from 'lodash`;
    
    console.log(_.toUpper('Hello, world !'))
  • Wenn Sie eine tsconfig.jsonDatei verwenden, stellen Sie sicher, dass Ihre Schreibdatei enthalten ist (oder nicht ausgeschlossen ist, Ihre Wahl), und machen Sie importim vorherigen Beispiel das Gleiche .

Für den Fall, dass keine Eingaben verfügbar sind. Sie haben zwei Möglichkeiten: Schreiben Sie Ihre eigene in eine .d.tsDatei oder ignorieren Sie die Typprüfung für die Bibliothek.

Importieren Sie die Bibliothek in eine Variable vom Typ, um die Typprüfung vollständig zu ignorieren (dies ist nicht die empfohlene Methode) any.

 const _: any = require('lodash');

 console.log(_.toUpper('Hello, world !'))

tscwerde mich beschweren, dass requirees nicht existiert. Geben Sie nodeEingaben ein oder declareverwerfen Sie den Fehler.

Blackus
quelle
2
Vollständige Antwort mit 3 Lösungen. +1
Offirmo
Ergänzung: Es funktioniert sogar mit ts-node, solange der Typisierungsindex intsconfig.json
Offirmo
Ich bin verwirrt von dem, was du meinst, "es zu deklarieren, um den Fehler zu verwerfen". Muss ich diese Änderung in dem Modul vornehmen, das ich importieren möchte?
Schnecke
1
Diese Antwort ist stark veraltet. Siehe meine neue Antwort unten stackoverflow.com/a/53786892/587407
Offirmo
48

[2018/12] Neue, aktuelle Antwort auf diese Frage, die ich 2016 gestellt habe, die trotz veralteter Antworten immer noch viel Aktivität zeigt.

Lange Rede kurzer Sinn , erfordert Typoskript Typen Informationen über Ihr Paket Code (auch bekannt als „ Typdeklaration Dateien “ aka „Typisierungen“) und sagt Ihnen , zu Recht , dass Sie sonst den ganzen Sinn der Typoskript verlieren würden. Es gibt verschiedene Lösungen, um sie bereitzustellen oder zu deaktivieren, die hier in der Reihenfolge der Best Practice aufgeführt sind:


Lösung 0 : Das Modul liefert bereits die Typisierungen. Wenn seine package.json eine Zeile wie diese enthält:

"typings": "dist/index.d.ts",

Es ist bereits TypeScript-fähig. Es ist höchstwahrscheinlich nicht der Fall, wenn Sie diese Seite lesen, also fahren wir fort ...


Lösung 1 : Verwenden Sie von der Community bereitgestellte Typisierungen von DefinitelyTyped . Versuchen Sie für ein Modul "foo" Folgendes:

npm add -D @types/foo

Wenn es funktioniert, Jackpot! Sie haben jetzt die Eingaben und können Ihr Modul verwenden. Wenn sich npm beschwert, dass das Modul @ types / foo nicht gefunden werden kann, fahren wir fort ...


Lösung 2 : Geben Sie benutzerdefinierte Typisierungen für dieses Modul an. (mit der Option, keine Anstrengung zu machen)

  1. Erstellen Sie einen Ordner mit dem Namen "typings-custom" im Stammverzeichnis Ihres Projekts
  2. Verweisen Sie auf den Inhalt dieses Ordners in Ihrer Datei tsconfig.json:
"include": [
    "./typings-custom/**/*.ts"
]
  1. Erstellen Sie eine Datei mit genau diesem Namen: foo.d.ts [foo = der Name des Moduls] mit dem Inhalt:
declare module 'foo'

Ihr TypeScript-Code sollte jetzt kompiliert werden, allerdings ohne Typinformationen (TypeScript betrachtet das foo-Modul vom Typ "any").

Sie können auch versuchen, die Typinformationen selbst zu schreiben, indem Sie sich das offizielle Dokument und / oder Beispiele von DefinitelyTyped ansehen . Wenn Sie dies tun, denken Sie daran, Ihre Eingaben entweder direkt in das Modul (Lösung 0, wenn der Modulautor dies akzeptiert) oder in DefinitelyTyped (Lösung 1) einzubringen.

Offirmo
quelle
1
@Offirmo, wir können auch mehrere benutzerdefinierte Eingaben in einer einzigen Datei deklarieren! Es sind also keine mehreren Dateien erforderlich (möglicherweise?).
Lazycipher
Schritt 2. Reference the content of this folder in your tsconfig.json:gibt den folgenden Fehler: Unknown compiler option 'include'.
Summe
1
@ Sumit es ist keine Compiler-Option, es sollte ein Geschwister voncompilerOptions
Offirmo
22

Sie vermissen wahrscheinlich die Deklarationsdateien .

Weitere Informationen finden Sie unter DefinitelyTyped .


Versuche dies:

npm install --save lodash
npm install --save @types/lodash

Jetzt können Sie importieren.

import _ from 'lodash';

Wenn das zu importierende Modul mehrere Exporte hat , können Sie dies tun:

import { Express, Router } from 'express';

Wenn das zu importierende Modul "keinen Standardexport hat" , müssen Sie Folgendes tun:

import * as http from 'http';
Derek Soike
quelle
Warum müssen wir verwenden * as _und nicht nur _ from 'lodash'wie im ES6-Code?
JohnnyQ
@ JohnnyQ Guter Punkt. import _ from 'lodash';In diesem Fall ist die Verwendung besser. Ich habe meine Antwort aktualisiert, um verschiedene Möglichkeiten zum Importieren und warum Sie sie verwenden würden, zu zeigen.
Derek Soike
1
Dies * as _ wird benötigt, wenn das Modul keinen Standardexport hat. Der tsc-Compiler warnt davor.
user2867342
Bedeutet "kein Standardexport", dass keine Typoskripttypen definiert sind (dh ein einfaches JavaScript-Modul importieren)? Ich bin neu in JS / Typescript ....
Big Rich
2
@BigRich "Kein Standardexport" bedeutet, dass das Modul keine export default <...>Anweisung hat. Schauen Sie sich den Abschnitt "Standardexporte" in der Dokumentation zu Typescript-Modulen an .
Derek Soike
4

Es hat bei mir funktioniert.

  1. Erstellen Sie einen Ordner mit dem Namen "Typings".
  2. Erstellen Sie im Ordner typings einen Dateinamen module-name.d.ts . Es beinhaltet:

    declare module "module-name";

  3. Verweisen Sie in tsconfig.json auf den Ordner

    "typeRoots": [ "./typings", "../node_modules/@types" ]

Quynh Ngo
quelle
Hallo! Vielen Dank für Ihren Beitrag. Diese Methode ist bereits in meiner Antwort enthalten und sollte nur als letztes Mittel verwendet werden.
Offirmo
Der Schritt 3 : In tsconfig.json, refer to the folder, gibt den folgenden Fehler:Unknown compiler option 'typesRoots'.
Summe
1
@ Sumit in meinem Fall, "typesRoots" ist in "compilerOptions"
Quynh Ngo
1
Es ist typeRoots, nicht typesRoots, und sollte sich in compilerOptions befinden
CM