Impossible d'importer les fichiers svg au format dactylographié


109

Dans les typescript(*.tsx)fichiers, je ne peux pas importer de fichier svg avec cette déclaration:

import logo from './logo.svg';

Transpiler dit: [ts] cannot find module './logo.svg'. Mon fichier svg est juste <svg>...</svg>.

Mais dans le .jsfichier, je suis capable de l'importer sans aucun problème avec exactement la même déclaration d'importation. Je suppose que cela a quelque chose à voir avec le type de fichier svg qui doit être défini d'une manière ou d'une autre pour ts transpiler.

Pourriez-vous s'il vous plaît partager comment faire fonctionner cela dans les fichiers TS?


2
Les fichiers svg ne sont pas javascript et ne peuvent pas être utilisés comme les modules javascript. Vous devriez plutôt charger ces fichiers en utilisant une requête http.
toskv

1
Utilisez-vous Webpack? C'est la seule chose que j'ai vue comprendre une telle importdéclaration. Webpack est peut-être ce qui permet cela dans votre JavaScript, mais il ne fait pas la même magie dans les fichiers TypeScript. (Je ne pense pas que TypeScript lui-même sache quoi faire ici.)
user94559

1
Si vous utilisez Webpack, vous devrez probablement partager votre configuration Webpack pour obtenir plus d'aide.
user94559

2
En lisant un peu plus à ce sujet, vous pouvez probablement faire const logo = require("./logo.svg");ou simplement ignorer l'erreur. (Je pense que TS devrait toujours produire le bon code.)
user94559

Merci beaucoup! nécessitent de bons travaux! Dans mon cas, ça doit être const logo = require("./logo.svg") as string;
AngryBoy

Réponses:


184

Si vous utilisez webpack, vous pouvez le faire en créant un fichier de types personnalisés.

Créez un fichier nommé custom.d.ts avec le contenu suivant:

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

Ajouter le custom.d.tsà tsconfig.jsoncomme ci-dessous

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

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


36
Vous devrez probablement l'ajouter à la includesection dans tsconfig.json .
Frederik Krautwald

12
Merci! Je savais qu'il devait être inclus quelque part mais je ne peux pas imaginer où. Même moi, je pensais que c'était dans tsconfig.json mais je ne savais pas comment le faire. Merci pour ton commentaire. J'ai fait une recherche et j'ai trouvé:"files": [ "custom.d.ts" ]
Shil Nevado

5
Vous pouvez obtenir une vérification de type pour le composant JSX en tapant le contenu:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
RedMatt

Est-il possible que le custom.d.tsfichier fonctionne globalement afin que le SVG puisse être dans un répertoire différent de celui du custom.d.tsfichier? J'obtiens une erreur "Impossible de trouver le module" sauf s'il se trouve dans le même répertoire.
Nic Scozzaro

1
Cela n'importe pas le contenu du fichier dans Angular, cela importe le nom de fichier sous forme de chaîne. J'ai besoin du contenu. Comment obtenir le contenu du fichier?
Routhinator

37

Merci smarx pour avoir signalé l'utilisation require(). Donc, dans mon cas, cela devrait être:

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

qui fonctionne bien dans les fichiers * .tsx


5
logopourrait être mieux nommé logoPath, car c'est ce que cela devient.
DharmaTurtle

2
@DharmaTurtle Je pense que cela peut être débattu. En outre, il est appelé logodans la question, donc c'est une meilleure réponse à cette question spécifique telle qu'elle est.
ArneHugo le

17

Ajoutez un custom.d.tsfichier (je l'ai créé sur le chemin racine de mon répertoire src) avec le type correct (grâce à RedMatt ):

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

Installez svg-react-loader ou un autre , puis:

  • Utilisez-le comme chargeur svg principal
  • Ou si vous migrez une base de code et que vous ne voulez pas toucher la partie de travail (JS), spécifiez le chargeur lors de l'importation:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Ensuite, utilisez-le simplement comme une balise JSX:

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

4

La solution que j'ai trouvée: dans le projet ReactJS, dans le fichier react-app-env.d.ts, vous supprimez simplement l'espace dans le commentaire tel que:

Avant

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

Après

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

J'espère t'aider


Pour les personnes qui utilisent create-react-app et eslint configuré, cela peut résoudre le problème
Daniel Chin

2

J'ai eu le même problème en essayant un tutoriel dactylographié REACT +.
Ce qui a fonctionné pour moi, c'est la déclaration d'importation suivante.

import * as logo from 'logo.svg'

Voici mes dépendances dans package.json.

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

J'espère que ça aide quelqu'un.


0

Il existe une autre façon de faire cela que nous avons implémentée: créer vos composants SVG. Je l'ai fait parce que cela me dérangeait d'utiliser des requiredéclarations commonJS à côté de mes imports.


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

si vous utilisez le slint puglin, il se peut qu'il ait désactivé en pensant que c'était un commentaire mais pas pour lire le svg, vous avez besoin de ce type de module de script, désactivez simplement la ligne et soyez heureux


0

Pour utiliser n actifs sur le code avec TypeScript , nous devons différer le type pour ces importations . Cela nécessite un fichier custom.d.ts qui signifie des définitions personnalisées pour TypeScript dans notre projet.

Configurons une déclaration pour les fichiers .svg:

custom.d.ts

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

Ici, nous déclarons un nouveau module pour les SVG en spécifiant toute importation qui se termine par .svg et en définissant le contenu du module comme any.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.