Я использую приложение create-response-app. Я пытаюсь вызвать изображение из моей общей папки из файла внутри моего src/components
. Я получаю это сообщение об ошибке.
./src/components/website_index.js Модуль не найден: вы попытались импортировать ../../public/images/logo/WC-BlackonWhite.jpg, который находится за пределами каталога проекта src /. Относительный импорт за пределами src / не поддерживается. Вы можете переместить его внутрь src / или добавить на него символическую ссылку из node_modules / проекта.
import logo from '../../public/images/logo_2016.png';
<img className="Header-logo" src={logo} alt="Logo" />
Я читал много вещей, в которых говорилось, что вы можете импортировать путь, но это все еще не работает для меня. Любая помощь будет принята с благодарностью. Я знаю, что есть много подобных вопросов, но все они говорят мне импортировать логотип или изображение настолько ясно, что я упускаю что-то в общей картине.
источник
../public/images/logo_2016.png
Вы поднялись дважды, сначала из папки компонентов, затем из папки src.public
папка находится прямо внутри вашейsrc
папки. В вашем комментарии без комментариев используется старый путь, начинающийся с,../..
поэтому вы не уверены, о чем вы думаете ?Ответы:
Это специальное ограничение, добавленное разработчиками create-react-app. Он реализован
ModuleScopePlugin
для того, чтобы файлы располагались вsrc/
. Этот плагин гарантирует, что относительный импорт из исходного каталога приложения не будет выходить за его пределы.Вы можете отключить эту функцию (одним из способов) с помощью
eject
проекта create-react-app.Большинство функций и их обновления скрыты внутри системы create-react-app. Если вы сделаете, у
eject
вас больше не будет некоторых функций и его обновления. Так что если вы не готовы управлять и настраивать приложение, включенное для настройки webpack и так далее - не выполняйтеeject
операцию.Играйте по существующим правилам (переходите в src). Но теперь вы можете узнать, как снять ограничение: сделать
eject
и удалитьModuleScopePlugin
из файла конфигурации webpack .Вместо этого
eject
есть промежуточные решения, такие как rewire, который позволяет программно изменять конфигурацию webpack безeject
. Но удаление вModuleScopePlugin
плагин не хорошо - это теряет некоторую защиту и не добавляет некоторые функции , доступные вsrc
.Лучше всего добавить полностью работающие дополнительные каталоги, подобные
src
. Это можно сделать с помощью response-app-rewire-aliasНе импортируйте из
public
папки - они будут дублироваться вbuild
папке и будут доступны по двум разным URL-адресам (или с разными способами загрузки), что в конечном итоге ухудшит размер загружаемого пакета.Импорт из
src
папки предпочтительнее и имеет преимущества. Все будет упаковано веб-пакетом в бандл с оптимальным размером чанков и для максимальной эффективности загрузки .источник
NODE_PATH=./src/..
в.env
файле. Таким образом, вы можете импортировать файлы из-за пределов папки src, не испытывая боли, связанной с извлечением вашего приложения.baseUrl
может быть установлен только наsrc
илиnode_modules
. Приложение Create React в настоящее время не поддерживает другие значения. Трюк с добавлением @ Flaom./src
тоже не помогает.Пакет react-app-rewired можно использовать для удаления плагина. Таким образом, вам не придется выталкивать.
Следуйте инструкциям на странице пакета npm (установите пакет и переверните вызовы в файле package.json) и используйте
config-overrides.js
файл, похожий на этот:const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); module.exports = function override(config, env) { config.resolve.plugins = config.resolve.plugins.filter(plugin => !(plugin instanceof ModuleScopePlugin)); return config; };
Это удалит ModuleScopePlugin из используемых плагинов WebPack, но оставит все остальное, как было, и устранит необходимость извлечения.
источник
react-app-rewired
с помощью [ github.com/arackaf/customize-crapting(customize-cra) . Тогда конфиг будет использовать толькоbabelInclude([path.resolve('src'), path.resolve('../common')])
иremoveModuleScopePlugin()
.config-overrides.js
файл, в который сможете поместить код.ModuleScopePlugin
плагина - не лучшая идея. Лучше добавить полностью рабочие дополнительные каталоги, аналогичныеsrc
использованиюЕсли ваши изображения находятся в общей папке, вам следует использовать
"/images/logo_2016.png"
в вашем
<img>
src
вместо импорта'../../public/images/logo_2016.png';
Это будет работать
<img className="Header-logo" src="/images/logo_2016.png" alt="Logo" />
источник
<img src="...">
<img src="/images/logo.png" alt="Logo" />
Чтобы предложить немного больше информации к другим ответам. У вас есть два варианта доставки файла .png пользователю. Структура файла должна соответствовать выбранному вами методу. Есть два варианта:
Используйте модуль system (
import x from y
), поставляемый с react-create-app, и свяжите его со своим JS. Поместите изображение вsrc
папку.Обслуживайте его из
public
папки и позвольте Node обслуживать файл. create-response-app также явно поставляется с переменной окружения, например<img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
. Это означает, что вы можете ссылаться на него в своем приложении React, но при этом он будет обслуживаться через Node, а ваш браузер запрашивает его отдельно в обычном запросе GET.Источник: create-response-app
источник
Удалите его с помощью Craco:
module.exports = { webpack: { configure: webpackConfig => { const scopePluginIndex = webpackConfig.resolve.plugins.findIndex( ({ constructor }) => constructor && constructor.name === 'ModuleScopePlugin' ); webpackConfig.resolve.plugins.splice(scopePluginIndex, 1); return webpackConfig; } } };
источник
Вам нужно перейти
WC-BlackonWhite.jpg
в свойsrc
каталог.public
Каталог для статических файлов , который будет связан непосредственно в HTML (например , как фавиконка), а не вещи , которые вы собираетесь импортировать непосредственно в пачку.источник
Есть несколько ответов, которые предоставляют решения
react-app-rewired
, ноcustomize-cra
предоставляют специальныйremoveModuleScopePlugin()
API, который немного более элегантен. (Это то же самое решение, но абстрагированноеcustomize-cra
пакетом.)npm i --save-dev react-app-rewired customize-cra
package.json
"scripts": { - "start": "react-scripts start" + "start": "react-app-rewired start", ... },
config-overrides.js
const { removeModuleScopePlugin } = require('customize-cra') module.exports = removeModuleScopePlugin()
источник
Я думаю, что решение Лукаса Баха по использованию response-app- rewired для изменения конфигурации webpack - хороший способ, однако я бы не исключил весь ModuleScopePlugin, а вместо этого внес бы в белый список конкретный файл, который можно импортировать за пределами src:
config-overrides.js
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin"); const path = require("path"); module.exports = function override(config) { config.resolve.plugins.forEach(plugin => { if (plugin instanceof ModuleScopePlugin) { plugin.allowedFiles.add(path.resolve("./config.json")); } }); return config; };
источник
установите эти два пакета
package.json
"scripts": { - "start": "react-scripts start" + "start": "react-app-rewired start" },
config-overrides.js
const { removeModuleScopePlugin } = require('customize-cra'); module.exports = function override(config, env) { if (!config.plugins) { config.plugins = []; } removeModuleScopePlugin()(config); return config; };
источник
Это ограничение гарантирует, что все файлы или модули (экспорт) находятся внутри
src/
каталога, в котором находится реализация./node_modules/react-dev-utils/ModuleScopePlugin.js
, в следующих строках кода.// Resolve the issuer from our appSrc and make sure it's one of our files // Maybe an indexOf === 0 would be better? const relative = path.relative(appSrc, request.context.issuer); // If it's not in src/ or a subdirectory, not our request! if (relative.startsWith('../') || relative.startsWith('..\\')) { return callback(); }
Вы можете снять это ограничение,
eject
потом удалитьModuleScopePlugin.js
из каталога.const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
из./node_modules/react-scripts/config/webpack.config.dev.js
PS: опасайтесь последствий выброса .
источник
Изображение в общей папке
use image inside html extension <img src="%PUBLIC_URL%/resumepic.png"/> use image inside js extension <img src={process.env.PUBLIC_URL+"/resumepic.png"}/>
источник
Извлекать не нужно, вы можете изменить
react-scripts
конфигурацию с помощью библиотеки rescriptsТогда это сработает:
module.exports = config => { const scopePluginIndex = config.resolve.plugins.findIndex( ({ constructor }) => constructor && constructor.name === "ModuleScopePlugin" ); config.resolve.plugins.splice(scopePluginIndex, 1); return config; };
источник
Если вам нужно импортировать только один файл, например README.md или package.json, его можно явно добавить в ModuleScopePlugin ().
config / paths.js
const resolveApp = relativePath => path.resolve(appDirectory, relativePath); module.exports = { appPackageJson: resolveApp('package.json'), appReadmeMD: resolveApp('README.md'), };
config / webpack.config.dev.js + config / webpack.config.prod.js
module.exports = { resolve: { plugins: [ // Prevents users from importing files from outside of src/ (or node_modules/). // This often causes confusion because we only process files within src/ with babel. // To fix this, we prevent you from importing files out of src/ -- if you'd like to, // please link the files into your node_modules/ and let module-resolution kick in. // Make sure your source files are compiled, as they will not be processed in any way. new ModuleScopePlugin(paths.appSrc, [ paths.appPackageJson, paths.appReadmeMD // README.md lives outside of ./src/ so needs to be explicitly included in ModuleScopePlugin() ]), ] } }
источник
Лучшее решение - форк
react-scripts
, это фактически упоминается в официальной документации, см .: Альтернативы извлечениюисточник
Если вам нужно несколько модификаций, например, при использовании дизайна муравьев , вы можете комбинировать несколько функций следующим образом:
const { override, removeModuleScopePlugin, fixBabelImports, } = require('customize-cra'); module.exports = override( fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css', }), removeModuleScopePlugin(), );
источник
Добавляя к ответу Бартека Мацейчека, вот как это выглядит с Craco:
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin"); const path = require("path"); module.exports = { webpack: { configure: webpackConfig => { webpackConfig.resolve.plugins.forEach(plugin => { if (plugin instanceof ModuleScopePlugin) { plugin.allowedFiles.add(path.resolve("./config.json")); } }); return webpackConfig; } } };
источник
Вы можете попробовать использовать симлинки, но в обратном порядке.
React не будет следовать симлинкам, но вы можете переместить что-нибудь в исходный каталог и создать на него симлинк.
В корне моего проекта у меня был каталог сервера узлов, в котором было несколько файлов схемы. Я хотел использовать их во внешнем интерфейсе, поэтому я:
ln -s SRC_PATH_OF_SCHEMA_FILE
Это дало возможность отреагировать на то, что он искал, и узел был совершенно счастлив, включая файлы через simlinks.
источник