Nie można zaimportować plików SVG w maszynie

130

W typescript(*.tsx)plikach nie mogę zaimportować pliku SVG z tym oświadczeniem:

import logo from './logo.svg';

Transpiler mówi: [ts] cannot find module './logo.svg'. Mój plik SVG jest po prostu <svg>...</svg>.

Ale w .jspliku mogę go zaimportować bez żadnych problemów z dokładnie tą samą instrukcją importu. Przypuszczam, że ma to coś wspólnego z typem pliku svg, który musi być jakoś ustawiony dla transpilera ts.

Czy mógłbyś podzielić się, jak to działa w plikach ts?

AngryBoy
źródło
2
svg nie są plikami javascript i nie mogą być używane tak jak moduły javascript. Zamiast tego powinieneś załadować te pliki za pomocą żądania http.
toskv
2
Czy używasz Webpack? To jedyna rzecz, jaką widziałem, jak rozumiem takie importstwierdzenie. Być może Webpack pozwala na to w twoim JavaScript, ale nie robi tej samej magii w plikach TypeScript. (Nie sądzę, żeby sam TypeScript wiedział, co tu robić.)
user94559
1
Jeśli używasz Webpacka, prawdopodobnie będziesz musiał udostępnić swoją konfigurację Webpacka, aby uzyskać dodatkową pomoc.
user94559
2
Czytając trochę więcej na ten temat, prawdopodobnie możesz zrobić const logo = require("./logo.svg");lub po prostu zignorować błąd. (Uważam, że TS powinien nadal
wysyłać
1
dlaczego, dlaczego Webpack / React musiał wszystko komplikować? Czy nie byłoby prościej po prostu zaimportować cokolwiek z plikiem import. Dla nowicjusza takiego jak ja te rzeczy mnie zniechęcają. Czy nie jesteśmy w 2020 roku, w którym „autokonfiguracja” powinna być normą?
SimpleGuy

Odpowiedzi:

210

Jeśli używasz pakietu webpack, możesz to zrobić, tworząc plik typów niestandardowych.

Utwórz plik o nazwie custom.d.ts z następującą zawartością:

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

Dodaj custom.d.tsdo tsconfig.jsonjak poniżej

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

Źródło: https://webpack.js.org/guides/typescript/#importing-other-assets

Graham
źródło
38
Prawdopodobnie należałoby dodać go do includesekcji w tsconfig.json .
Frederik Krautwald
12
Dzięki! Wiedziałem, że musi być gdzieś zawarty, ale nie mogę sobie wyobrazić, gdzie. Nawet myślałem, że jest w tsconfig.json, ale nie wiedziałem, jak to zrobić. Dziękuję za komentarz. "files": [ "custom.d.ts" ]
Poszukałem
6
Możesz sprawdzić typ komponentu JSX, wpisując jego zawartość:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
RedMatt
1
Czy możliwe jest, aby custom.d.tsplik działał globalnie, aby plik SVG mógł znajdować się w innym katalogu niż custom.d.tsplik? Wyświetlany jest błąd „nie można znaleźć modułu”, chyba że znajduje się on w tym samym katalogu.
Nic Scozzaro
1
To nie importuje zawartości pliku w Angular, importuje nazwę pliku jako ciąg. Potrzebuję treści. Jak otrzymujemy zawartość pliku?
Routhinator
38

Dzięki smarx za wskazanie użycia require(). Więc w moim przypadku powinno to być:

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

który działa dobrze w plikach * .tsx

AngryBoy
źródło
7
logomogłaby być lepiej nazwana logoPath, bo tak właśnie się staje.
DharmaTurtle
2
@DharmaTurtle Myślę, że można o tym dyskutować. Jest to również wywołane logow pytaniu, więc jest lepszą odpowiedzią na to konkretne pytanie.
ArneHugo
@DharmaTurtle, szczerze koleś, nazwa zmiennej jest daleko na uboczu, po co rozpraszać się tak trywialną rzeczą?
ELI7VH
19

Dodaj custom.d.tsplik (utworzyłem go na ścieżce głównej mojego katalogu src) z odpowiednim typem (dzięki RedMatt ):

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

Zainstaluj svg-react-loader lub inny , a następnie:

  • Użyj go jako głównego programu ładującego svg
  • Lub, jeśli migrujesz bazę kodu i nie chcesz dotykać części roboczej (JS), określ moduł ładujący podczas importu:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Następnie użyj go jako tagu JSX:

function f() { 
  return (<MySVG />); 
}
Allenaz
źródło
7

Rozwiązanie, które znalazłem: W projekcie ReactJS w pliku React-app-env.d.ts po prostu usuwasz spację w komentarzu np .:

Przed

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

Po

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

Mam nadzieję, że ci pomogę

jilvanx
źródło
Dla osób, które używają aplikacji create-react-app i skonfigurowanego eslint, może to rozwiązać problem
Daniel Chin
4

Miałem ten sam problem podczas wypróbowywania samouczka na maszynie REACT +.
U mnie zadziałało następujące oświadczenie dotyczące importu.

import * as logo from 'logo.svg'

Oto moje zależności w package.json.

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

Mam nadzieję, że to komuś pomoże.

Kiran Mohan
źródło
2

Wdrożyliśmy alternatywny sposób: utwórz komponenty SVG. Zrobiłem to, ponieważ denerwowało mnie, że używam zwykłych requireinstrukcji JS obok moich import.

endymion1818
źródło
2

Aby użyć n zasobów w kodzie z TypeScript , musimy odroczyć typ tych importów . Wymaga to pliku custom.d.ts , który oznacza niestandardowe definicje dla języka TypeScript w naszym projekcie.

Ustawmy deklarację dla plików .svg:

custom.d.ts

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

Tutaj deklarujemy nowy moduł dla plików SVG, określając dowolny import, który kończy się na .svg i definiując zawartość modułu jako dowolną.

Mehadi Hassan
źródło
0
    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

jeśli używasz puglin slint może być tak, że wyłączył myślenie, że to komentarz, ale nie chcesz czytać svg, potrzebujesz tego modułu skryptu typu po prostu wyłącz linię i bądź szczęśliwy

Breno Melo
źródło
-1

Udało mi się to zrobić *.svg, wykonując następujące czynności:

zainstalować next-images

cd /to/ur/root
npm install --save next-images

aktualizacja next.config.js

Jeśli nie masz next.config.jspliku, utwórz go w katalogu głównym. Następnie dodaj:

const withImages = require('next-images')
module.exports = withImages()

standardowy import powinien teraz działać

import icon from './icons/thaticon.svg';
Harley Lang
źródło
Widzę, że to głosowanie zostało odrzucone. Daj mi znać, jeśli masz jakieś uwagi dotyczące tej odpowiedzi, a będziemy mogli je odpowiednio dostosować.
Harley Lang