J'utilise create-react-app. J'essaie d'appeler une image de mon dossier public à partir d'un fichier dans mon src/components
. Je reçois ce message d'erreur.
./src/components/website_index.js Module introuvable: vous avez tenté d'importer le fichier ../../public/images/logo/WC-BlackonWhite.jpg qui se trouve en dehors du répertoire src/du projet. Les importations relatives en dehors de src/ne sont pas prises en charge. Vous pouvez soit le déplacer à l'intérieur de src /, soit lui ajouter un lien symbolique à partir de node_modules/du projet.
import logo from '../../public/images/logo_2016.png'; <img className="Header-logo" src={logo} alt="Logo" />
J'ai lu beaucoup de choses disant que vous pouvez importer le chemin mais cela ne fonctionne toujours pas pour moi. Toute aide serait grandement appréciée. Je sais qu'il y a beaucoup de questions comme celle-ci, mais ils me disent tous d'importer un logo ou une image si clairement que je manque quelque chose dans la grande image.
Ceci est une restriction spéciale ajoutée par les développeurs de create-react-app. Il est implémenté dans ModuleScopePlugin
pour garantir que les fichiers résident dans src/
. Ce plug-in garantit que les importations relatives depuis le répertoire source de l'application ne vont pas en dehors de celui-ci.
Vous pouvez désactiver cette fonctionnalité, mais uniquement après le eject
opération du projet create-react-app.
La plupart des fonctionnalités et leurs mises à jour sont cachées dans les composants internes du système create-react-app. Si vous faites eject
vous n'aurez plus certaines fonctionnalités et sa mise à jour. Donc, si vous n'êtes pas prêt à gérer et à configurer l'application incluse pour configurer Webpack, etc., ne faites pas l'opération eject
.
Jouez selon les règles existantes (déplacez vers src). Mais maintenant, vous pouvez savoir comment supprimer la restriction: faites eject
et supprimez ModuleScopePlugin
du fichier de configuration de Webpack .
Depuis créer-réagir-application v0.4. la variable d'environnement NODE_PATH
permet de spécifier un chemin pour l'importation absolue .
L'importation absolue permet d'utiliser import App from 'App'
à la place de import App from './App'
par rapport à la valeur spécifiée dans la variable NODE_PATH
.
Cette fonctionnalité est particulièrement utile pour les questions de monorepos ou de configuration, mais pas pour importer des images ou toute autre chose du dossier public
.
Le contenu du dossier public
sera placé dans le dossier build
et sera disponible par l'URL relative. De même, tout ce qui est importé sera traité par Webpack et sera également placé dans le dossier build
.
Si vous importez quelque chose à partir du dossier public
, il sera probablement dupliqué dans le dossier build
et sera disponible sous deux URL différentes (ou avec des méthodes de chargement différentes), ce qui aggravera la taille du téléchargement du paquet.
L'importation à partir du dossier src est préférable et présente des avantages. Tout sera emballé par Webpack dans le paquet avec des morceaux de taille optimale et pour la meilleure efficacité de chargement .
Pour offrir un peu plus d'informations aux réponses des autres. Vous avez deux options pour la livraison du fichier .png à l'utilisateur. La structure de fichier doit être conforme à la méthode choisie. Les deux options sont:
Utilisez le système de module (import x from y
) fourni avec react-create-app et associez-le à votre JS. Placez l'image dans le dossier src
.
Servez-le à partir du dossier public
et laissez Node servir le fichier. create-react-app est apparemment livré avec une variable d'environnement, par exemple. <img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
. Cela signifie que vous pouvez le référencer dans votre application React tout en le faisant toujours passer par Node, votre navigateur vous le demandant séparément dans une requête GET normale.
Source: create-react-app
Le package react-app-rewired peut être utilisé pour supprimer le plugin. De cette façon, vous ne devez pas éjecter.
Suivez les étapes de la page du package npm (installez le package et inversez les appels dans le fichier package.json) et utilisez un fichier config-overrides.js
similaire à celui-ci:
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;
};
Cela supprimera le ModuleScopePlugin des plugins WebPack utilisés, mais laissera le reste tel quel et éliminera la nécessité d'éjecter.
Si vos images sont dans le dossier public, vous devez utiliser
"/images/logo_2016.png"
dans votre <img>
src
au lieu d'importer
'../../public/images/logo_2016.png';
Ça va marcher
<img className="Header-logo" src="/images/logo_2016.png" alt="Logo" />
Vous devez déplacer WC-BlackonWhite.jpg
dans votre répertoire src
. Le répertoire public
est destiné aux fichiers statiques qui seront liés directement dans le code HTML (tel que le favicon), et non aux éléments que vous allez importer directement dans votre bundle.
Cette restriction garantit que tous les fichiers ou modules (exportations) se trouvent dans le répertoire src/
, que l'implémentation est dans ./node_modules/react-dev-utils/ModuleScopePlugin.js
, dans les lignes de code suivantes.
// 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();
}
Vous pouvez supprimer cette restriction en
eject
puis supprimez ModuleScopePlugin.js
du répertoire.const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
de ./node_modules/react-scripts/config/webpack.config.dev.js
PS: Méfiez-vous des conséquences de éjecter .
la meilleure solution consiste à bifurquer react-scripts
, ce qui est effectivement mentionné dans la documentation officielle, voir: Alternatives à l'éjection
Si vous ne devez importer qu'un seul fichier, tel que README.md ou package.json, vous pouvez l'ajouter explicitement à 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()
]),
]
}
}
Vous n'avez pas besoin d'éjecter, vous pouvez modifier le react-scripts
config avec le bibliothèque de rescripts
Cela fonctionnerait alors:
module.exports = config => {
const scopePluginIndex = config.resolve.plugins.findIndex(
({ constructor }) => constructor && constructor.name === "ModuleScopePlugin"
);
config.resolve.plugins.splice(scopePluginIndex, 1);
return config;
};