Почему я должен использовать require вместо import from для изображения в React?

Я вижу, что этот ответ предлагает синтаксис для импорта изображений, как показано ниже (закомментировано). В моем случае это не сработало (жалуется, что в этом файле нет модулей для поиска), и мне пришлось переключиться на активный в данный момент синтаксис.

// import Author from "../assets/author.png";
var Author = require("../assets/author.png");

Разница, которую я могу себе представить, заключается в том, что я использую TypeScript (транспилирую свой TSX с помощью awesome-typescript-loader и загружаю свой PNG file-loader), а они, похоже, используют JSX . Но, насколько я понимаю, все это транспилируется в простой JS и, в конце концов, require.

Будучи новичком в React, я не уверен, в чем причина этого несоответствия, но также я не уверен, что искать в Google, чтобы исследовать себя.


person DonkeyBanana    schedule 18.09.2018    source источник
comment
См. ответы на этот вопрос   -  person Aruna Herath    schedule 21.09.2018


Ответы (4)


Вы можете объявить модуль для ваших изображений следующим образом:

declare module "*.png" {
  const value: any;
  export default value;
}

Затем вы сможете импортировать свое изображение следующим образом:

import AuthorSrc from "../assets/author.png";

Это происходит потому, что веб-пакет не поддерживает импорт изображений из коробки. Поэтому вам нужно добавить правило для этого в конфигурационный файл веб-пакета. Когда вы добавляете новое правило, TypeScript не знает об этом автоматически, поэтому вам нужно объявить новый модуль, чтобы решить эту проблему. Без модуля вы сможете импортировать изображения, но TypeScript выдаст ошибку, потому что вы не сказали, что это возможно.

person Vincent D'amour    schedule 21.09.2018
comment
Кажется, ошибка устранена, но я не вижу изображение, только рамку вокруг него, а фон такой же, как и остальная часть страницы. Я использую следующее правило для загрузки изображения: {test: /\.(png)$/,use: [{ loader: file-loader }]}. Можете ли вы представить себе более подходящий? - person DonkeyBanana; 28.09.2018
comment
Кроме того, мне интересно, если значение const: any; экспортировать значение по умолчанию; эквивалентно простой установке точки с запятой вместо фигурных скобок. Я видел, как люди объявляют модуль следующим образом: declare module bzz; и мне непонятно, является ли это сокращением для declare module bzz{...}. - person DonkeyBanana; 28.09.2018

Это больше проблема машинописного текста, чем самого веб-пакета, вам может потребоваться объявить модули в файле объявления.

Создайте declarations.d.ts

Обновите свой tsconfig.json

"include": [
    "./declarations.d.ts",
],

Поместите это в этот файл:

declare module '*.png';

Ошибка может исчезнуть.

person PlayMa256    schedule 18.09.2018
comment
Нет, я сделал так, как вы предложили, и ошибка остается. Он по-прежнему жалуется на то, что не может найти модуль, и изображение не отображается. - person DonkeyBanana; 18.09.2018
comment
ну, это выходит за рамки того, что я знаю от ТС. Можете ли вы поделиться всем сообщением об ошибке? - person PlayMa256; 18.09.2018
comment
ОШИБКА в [at-loader]./src/components/MainArea.tsx:3:21, а затем TS2307: не удается найти модуль '../assets/author.png'. - person DonkeyBanana; 19.09.2018

Эта проблема не имеет никакого отношения к веб-пакету или любому сборщику и не совсем проблема с машинописным текстом.

Typescript заявил, что `require("path") - это способ включения модулей в область действия вашего текущего модуля, в то время как его также можно использовать для чтения некоторых случайных файлов (например, файлов json).

Как указали Винсент и Playma256, вы можете объявить подстановочный знак модуля для соответствия определенным типам файлов, чтобы вы могли импортировать его как оператор импорта. Но вам действительно не нужно этого делать. Typescript не выдаст вам ошибку, если вы пытаетесь импортировать файл png или json (может быть, tslint, но это зависит от вашей конфигурации).

Кстати, если ваше объявление находится в исходной папке вашего проекта, как определено в tsconfig.json, вам не нужно включать его, как указано Playma256.

Я создал пример проекта в узле для тестирования:

https://github.com/rodrigoelp/typescript-declare-files

person rodrigoelp    schedule 24.09.2018
comment
Я не совсем уверен, что это правильно. Если я правильно понимаю, вы импортируете файл JSON, а не изображение, и на самом деле это может иметь значение из-за того, какой загрузчик вы используете, не так ли? Я использую file-loader для моего PNG, и я вижу границу вокруг места, где должно быть изображение (но нет настоящее изображение). Вы действительно смогли видеть отображаемое изображение? (Сообщение об ошибке исчезает, так что ответ вроде правильный, но я бы хотел увидеть и автора, хе-хе.) - person DonkeyBanana; 28.09.2018
comment
Кроме того, я видел как declare module.xxx;*, так и declare module.xxx{const v:any;return default v}*. Они эквивалентны? - person DonkeyBanana; 28.09.2018
comment
Привет @DonkeyBanana, пытаюсь дать вам немного контекста: какой загрузчик я использую? если вы имели в виду упаковщик, я протестировал его непосредственно с узлом, но он также был протестирован с веб-пакетом и метро. Я импортирую файл json, а не png, компиляция, выполненная машинописным текстом, будет такой же. Любой оператор импорта транслируется в требование, AFAIK. Не должно иметь никакого значения. Когда я провел свой небольшой тест, я увидел изображение, но мой тест был выполнен с использованием реакции (что, я думаю, то же самое, что вы делаете) - person rodrigoelp; 29.09.2018
comment
В отношении: Является ли declare module "*.xxx"; эквивалентом declare module "*.xxx" { const v: any; export default v }? Нет, первый просто объявляет о существовании модуля с таким именем, второй сообщает машинописному тексту, что ему необходимо по умолчанию захватить экземпляр или определение, которое было экспортировано. - person rodrigoelp; 29.09.2018
comment
Прошу извинить меня за невежество при формулировке вопроса. Я не имел в виду тип упаковщика (кстати, я всегда использую Webpack). Однако при его настройке есть раздел для правил, и в нем мне пришлось указать awesome-typescript-loader для TS, style-loader, css -loader и sass-loader для SCSS, а также file-loader, который предположительно требуется для статических файлов (например, моего PNG). Я спрашиваю, является ли file-loader предпочтительным для конфигурации Webpack для отображения изображений PNG на странице. - person DonkeyBanana; 29.09.2018
comment
А, теперь я понимаю. Да, file-loader — один из самых популярных. если вы попытаетесь импортировать изображение, вызвав import fileName from "./whatever.png", убедитесь, что у вас есть правильная конфигурация (например, publicPath или регулярное выражение для поиска файлов, которые вы хотите найти), в противном случае импорт даст вам undefined, что в основном означает, что не найдено и вы закончите со сценарием, указанным выше. - person rodrigoelp; 01.10.2018
comment
Один из способов проверить это — просто вызвать require("./fileName.png") и настроить свой webpack.config.js с помощью publicPath в папку с ресурсами (где вы сохранили все изображения). Если вы зарегистрируете его в консоли, вы сможете увидеть, был ли неопределенный экземпляр или фактическое изображение. В качестве альтернативы настройте vscode для запуска каждой строки (вам нужно скомпилировать с помощью sourceMaps) и проверьте, что экземпляр не undefined - person rodrigoelp; 01.10.2018

Я думаю, вы можете решить эту проблему с помощью Webpack&&typescript. Официальная веб-страница webpack представила кое-что об этом в https://webpack.js.org/guides/typescript/ И я попробовал это сам в https://github.com/reactpersopnal/webpack-root/tree/feature/typescript Причина в том, что вы хотели бы использовать активы без кода с TypeScript, поэтому нам нужно отложить тип для этого импорта для webpack. Вы можете просто добавить custom.d.ts.

declare module "*.jpg" {
    const content: any;
    export default content;
}
person Root    schedule 25.09.2018