Неможливо імпортувати файли 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.