Неможливо імпортувати файли svg у машинопис


109

У typescript(*.tsx)файлах я не можу імпортувати файл svg із цим твердженням:

import logo from './logo.svg';

Transpiler каже: [ts] cannot find module './logo.svg'. Мій файл svg просто <svg>...</svg>.

Але у .jsфайлі я можу імпортувати його без будь-яких проблем із точно тим самим оператором імпорту. Я припускаю, що це має щось спільне з типом файлу svg, який потрібно якось встановити для ts transpiler.

Не могли б ви поділитися, як це зробити у файлах ts?


2
Файли svg не є javascript і не можуть використовуватися як модулі javascript. Ви повинні завантажувати ці файли, використовуючи http-запит.
toskv

1
Ви використовуєте Webpack? Це єдине, що я бачив, що розуміє таке importтвердження. Можливо, Webpack - це те, що дозволяє це робити у вашому JavaScript, але він не робить тієї самої магії у файлах TypeScript. (Я не думаю, що TypeScript сам знає, що тут робити.)
user94559

1
Якщо ви використовуєте Webpack, вам, мабуть, доведеться надати конфігурацію Webpack, щоб отримати додаткову допомогу.
user94559

2
Прочитавши трохи більше про це, ви, мабуть, можете зробити const logo = require("./logo.svg");або просто проігнорувати помилку. (Я вважаю, що TS все одно повинен видавати правильний код.)
user94559

дуже тобі дякую! вимагають хороших робіт! У моєму випадку це має бути const logo = require("./logo.svg") as string;
AngryBoy

Відповіді:


185

Якщо ви використовуєте webpack, ви можете зробити це, створивши файл власних типів.

Створіть файл custom.d.ts із таким вмістом:

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

Додайте custom.d.tsдо, tsconfig.jsonяк показано нижче

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

Джерело: https://webpack.js.org/guides/typescript/#importing-other-assets


36
Ймовірно, вам потрібно буде додати його до includeрозділу в tsconfig.json .
Фредерік Краутвальд,

12
Дякую! Я знав, що його потрібно десь включити, але я не можу уявити, куди. Навіть я думав, що це в tsconfig.json, але я не знав, як це зробити. Дякую за ваш коментар. Я зробив обшук і виявив:"files": [ "custom.d.ts" ]
Шил Невадо,

5
Ви можете перевірити тип компонента JSX, набравши вміст:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
RedMatt

Чи можливо, щоб custom.d.tsфайл працював глобально, щоб SVG міг знаходитися в іншому каталозі, ніж custom.d.tsфайл? Я отримую повідомлення про помилку "не можу знайти модуль", якщо він не знаходиться в тому ж каталозі.
Nic Scozzaro

1
Це не імпортує вміст файлу в Angular, воно імпортує ім'я файлу як рядок. Мені потрібен вміст. Як отримати вміст файлу?
Рутінатор

37

Дякуємо smarx за вказівку на використання require(). Тож у моєму випадку це має бути:

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

який чудово працює у файлах * .tsx


5
logoможливо, його краще назвати logoPath, бо таким воно і стає.
DharmaTurtle

2
@DharmaTurtle Я думаю, що про це можна дискутувати. Крім того, це називається logoу питанні, тому це краща відповідь на це конкретне питання, як воно є.
ArneHugo

17

Додайте custom.d.tsфайл (я створив його на кореневому шляху мого каталогу rc ) правильного типу (завдяки RedMatt ):

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

Встановіть svg-response-loader або інший , а потім:

  • Використовуйте його як основний завантажувач svg
  • Або якщо ви переносите кодову базу і не хочете торкатися робочої частини (JS), вкажіть завантажувач при імпорті:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Тоді просто використовуйте його як тег JSX:

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

4

Рішення, яке я знайшов: у проекті ReactJS у файлі response-app-env.d.ts ви просто видаляєте простір у коментарі, наприклад:

До цього

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

Після

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

Я сподіваюся допомогти вам


Для людей, які використовують додаток create-response-app та налаштований eslint, це може вирішити проблему
Daniel Chin,

2

У мене була та ж проблема під час випробування підручника з машинопису REACT +.
Для мене спрацювала наступна заява про імпорт.

import * as logo from 'logo.svg'

Ось мої залежності в package.json.

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

Сподіваюся, це комусь допомагає.


1

Щоб використовувати n вбудованих кодових ресурсів із TypeScript , нам потрібно відкласти тип для цього імпорту . Для цього потрібен файл custom.d.ts, який позначає власні визначення для TypeScript у нашому проекті.

Давайте налаштуємо декларацію для файлів .svg:

custom.d.ts

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

Тут ми оголошуємо новий модуль для SVG, вказуючи будь-який імпорт, який закінчується на .svg, і визначаючи вміст модуля як будь-який.


0

Існує альтернативний спосіб зробити це, який ми впровадили: створіть компоненти SVG. Я зробив це, тому що мене злякало, що я використовую загальні requireзаяви JS поряд зі своїм imports.


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

якщо ви використовуєте шліфт puglin, можливо, він відключив, думаючи, що це коментар, але не для читання svg, вам потрібен цей модуль сценарію типу, просто відключіть рядок і будьте щасливі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.