Невозможно импортировать файлы SVG в машинописный текст

115

В typescript(*.tsx)файлах я не могу импортировать файл svg с этим утверждением:

import logo from './logo.svg';

Transpiler говорит: [ts] cannot find module './logo.svg'. Мой файл svg просто <svg>...</svg>.

Но в .jsфайле я могу импортировать его без каких-либо проблем с точно таким же оператором импорта. Я полагаю, это как-то связано с типом файла svg, который должен быть каким-то образом установлен для транспилятора ts.

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

AngryBoy
источник
2
Файлы svg не являются javascript и не могут использоваться в качестве модулей javascript. Вместо этого вы должны загружать эти файлы с помощью HTTP-запроса.
toskv
2
Вы используете 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

Ответы:

191

Если вы используете 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 03
1
Это не импортирует содержимое файла в Angular, а импортирует имя файла в виде строки. Мне нужен контент. Как нам получить содержимое файла?
Routhinator
37

Спасибо smarx за указание на использование require(). Так что в моем случае это должно быть:

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

который отлично работает в файлах * .tsx

AngryBoy
источник
5
logoможно было бы лучше назвать logoPath, потому что это то, чем оно становится.
DharmaTurtle
2
@DharmaTurtle Я думаю, это можно обсуждать. Кроме того, logoон вызывается в вопросе, так что это лучший ответ на этот конкретный вопрос как таковой.
ArneHugo,
@DharmaTurtle, честно говоря, чувак, имя переменной не имеет значения, зачем отвлекаться на такую ​​тривиальную вещь?
ELI7VH,
17

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

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

Установите svg-react-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" />

Я надеюсь помочь тебе

Jilvanx
источник
Для людей, которые используют приложение create-response-app и настроили eslint, это может решить проблему
Дэниел Чин,
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"
  },

Надеюсь, это кому-то поможет.

Киран Мохан
источник
0

Есть альтернативный способ сделать это, который мы реализовали: создать компоненты SVG. Я сделал это, потому что меня беспокоило, что я использую commonJS requireвместе с моими imports.

эндимион1818
источник
0
    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

если вы используете puglin slint, возможно, он отключил, думая, что это был комментарий, но не для чтения svg, вам нужен модуль сценария этого типа, просто отключите строку и будьте счастливы

Брено Мело
источник
0

Чтобы использовать n ресурсов в коде с TypeScript , нам нужно отложить тип для этого импорта . Для этого требуется файл custom.d.ts, который обозначает пользовательские определения для TypeScript в нашем проекте.

Давайте настроим объявление для файлов .svg:

custom.d.ts

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

Здесь мы объявляем новый модуль для SVG, указывая любой импорт, заканчивающийся на .svg, и определяя содержимое модуля как любое.

Мехади Хасан
источник