SVG-Dateien können nicht in Typoskript importiert werden

106

In typescript(*.tsx)Dateien kann ich keine SVG-Datei mit dieser Anweisung importieren:

import logo from './logo.svg';

Transpiler sagt: [ts] cannot find module './logo.svg'. Meine SVG-Datei ist nur <svg>...</svg>.

Aber in .js Datei kann ich es ohne Probleme mit genau der gleichen Importanweisung importieren. Ich nehme an, es hat etwas mit dem Typ der SVG-Datei zu tun, die irgendwie für den Transpiler eingestellt werden muss.

Könnten Sie bitte mitteilen, wie dies in ts-Dateien funktioniert?

Wütender Junge
quelle
2
SVG-Dateien sind kein Javascript und können nicht wie Javascript-Module verwendet werden. Sie sollten diese Dateien stattdessen über eine http-Anforderung laden.
toskv
1
Verwenden Sie Webpack? Das ist das einzige, was ich gesehen habe, um eine solche importAussage zu verstehen . Vielleicht erlaubt Webpack dies in Ihrem JavaScript, aber es macht nicht die gleiche Magie in TypeScript-Dateien. (Ich glaube nicht, dass TypeScript selbst weiß, was hier zu tun ist.)
user94559
1
Wenn Sie Webpack verwenden, müssen Sie wahrscheinlich Ihre Webpack-Konfiguration freigeben, um weitere Hilfe zu erhalten.
user94559
2
Wenn Sie etwas mehr darüber lesen, können Sie const logo = require("./logo.svg");den Fehler wahrscheinlich tun oder einfach ignorieren. (Ich glaube, TS sollte immer noch den richtigen Code ausgeben.)
user94559
vielen Dank! erfordern funktioniert gut! In meinem Fall muss es sein const logo = require("./logo.svg") as string;
AngryBoy

Antworten:

181

Wenn Sie Webpack verwenden, können Sie dies tun, indem Sie eine benutzerdefinierte Typdatei erstellen.

Erstellen Sie eine Datei mit dem Namen custom.d.ts mit folgendem Inhalt:

declare module "*.svg" {
  const content: any;
  export default content;
}

Fügen Sie die custom.d.tszu tsconfig.jsonwie unten

"include": ["src/components", "src/custom.d.ts"]

Quelle: https://webpack.js.org/guides/typescript/#importing-other-assets

Graham
quelle
36
Wahrscheinlich müssen Sie es dem includeAbschnitt in tsconfig.json hinzufügen .
Frederik Krautwald
12
Vielen Dank! Ich wusste, dass es irgendwo enthalten sein muss, aber ich kann mir nicht vorstellen, wo. Sogar ich dachte, es wäre in tsconfig.json, aber ich wusste nicht, wie es geht. Vielen Dank für Ihren Kommentar. Ich habe eine Suche durchgeführt und festgestellt:"files": [ "custom.d.ts" ]
Shil Nevado
5
Sie können eine Typprüfung für die JSX-Komponente erhalten, indem Sie den Inhalt eingeben:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
RedMatt
Ist es möglich, dass die custom.d.tsDatei global funktioniert, sodass sich die SVG in einem anderen Verzeichnis als die custom.d.tsDatei befinden kann? Ich erhalte die Fehlermeldung "Modul kann nicht gefunden werden", es sei denn, es befindet sich im selben Verzeichnis.
Nic Scozzaro
1
Dadurch wird der Inhalt der Datei nicht in Angular importiert, sondern der Dateiname wird als Zeichenfolge importiert. Ich brauche den Inhalt. Wie bekommen wir den Inhalt der Datei?
Routhinator
37

Vielen Dank an smarx für den Hinweis auf die Verwendung require(). In meinem Fall sollte es also sein:

const logo = require("./logo.svg") as string;

Das funktioniert gut in * .tsx-Dateien

Wütender Junge
quelle
5
logokönnte besser benannt sein logoPath, denn so wird es.
DharmaTurtle
2
@ DharmaTurtle Ich denke, das kann diskutiert werden. Außerdem wird es logoin der Frage aufgerufen , sodass es eine bessere Antwort auf diese spezielle Frage ist.
ArneHugo
17

Fügen Sie eine custom.d.tsDatei (ich habe sie im Stammpfad meines src-Verzeichnisses erstellt) mit dem richtigen Typ hinzu (dank RedMatt ):

declare module '*.svg' {
  const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
  export default content;
}

Installieren Sie svg-react-loader oder einen anderen , dann:

  • Verwenden Sie es als Haupt-SVG-Loader
  • Oder wenn Sie eine Codebasis migrieren und den Arbeitsteil (JS) nicht berühren möchten, geben Sie den Loader beim Import an:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Verwenden Sie es dann einfach als JSX-Tag:

function f() { 
  return (<MySVG />); 
}
Allenaz
quelle
4

Die Lösung, die ich gefunden habe: Im ReactJS-Projekt entfernen Sie in der Datei react-app-env.d.ts einfach das Leerzeichen im Kommentar, z.

Vor

// / <reference types="react-scripts" />

Nach dem

/// <reference types="react-scripts" />

ich hoffe Dir zu helfen

jilvanx
quelle
Für Leute, die die Create-React-App verwenden und eslint konfiguriert haben, kann dies das Problem lösen
Daniel Chin
2

Ich hatte das gleiche Problem beim Ausprobieren eines REACT + Typoskript-Tutorials.
Was für mich funktioniert hat, war die folgende Importanweisung.

import * as logo from 'logo.svg'

Hier sind meine Abhängigkeiten in package.json.

  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-scripts-ts": "3.1.0"
  },

Hoffe es hilft jemandem.

Kiran Mohan
quelle
1

Um n On-Code-Assets mit TypeScript zu verwenden , müssen Sie den Typ für diese Importe verschieben . Dies erfordert eine Datei custom.d.ts , die benutzerdefinierte Definitionen für TypeScript in unserem Projekt angibt .

Lassen Sie uns eine Deklaration für .svg-Dateien einrichten:

custom.d.ts

declare module "*.svg" {
  const content: any;
  export default content;
}

Hier deklarieren wir ein neues Modul für SVGs, indem wir einen Import angeben, der mit .svg endet, und den Inhalt des Moduls als einen beliebigen definieren.

Mehadi Hassan
quelle
0

Es gibt eine alternative Möglichkeit, die wir implementiert haben: Erstellen Sie Ihre SVG-Komponenten. Ich habe dies getan, weil es mich nervte, dass ich requireneben meinen imports commonJS- Anweisungen verwendete .

endymion1818
quelle
0
    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

Wenn Sie den Puglin Slint verwenden, kann es sein, dass er deaktiviert hat, weil er dachte, es sei ein Kommentar, aber um das SVG nicht zu lesen, benötigen Sie dieses Skriptmodul. Deaktivieren Sie einfach die Zeile und seien Sie glücklich

Breno Melo
quelle