私はcreate-react-appを使っています。 src/components
内のファイルから私のパブリックフォルダから画像を呼び出そうとしています。このエラーメッセージが表示されます。
./src/components/website_index.jsモジュールが見つかりません:プロジェクトsrc /ディレクトリの外にある../../public/images/logo/WC-BlackonWhite.jpgをインポートしようとしました。 src /外への相対インポートはサポートされていません。 src /の中に移動するか、プロジェクトのnode_modules /からシンボリックリンクを追加することができます。
import logo from '../../public/images/logo_2016.png'; <img className="Header-logo" src={logo} alt="Logo" />
私はあなたがパスへのインポートをすることができると言う多くのことを読みました、しかしそれはまだ私のために働いていません。任意の助けは大歓迎です。私はこのような質問がたくさんあることを知っていますが、それらはすべてロゴや画像をインポートするように私に言っているので明らかに私は全体像の中に何かが足りないのです。
これはcreate-react-appの開発者によって追加された特別な制限です。ファイルがsrc/
に存在することを保証するためにModuleScopePlugin
に実装されています。そのプラグインは、アプリのソースディレクトリからの相対的なインポートがそれの外側に届かないことを保証します。
この機能を無効にできるのは、create-react-appプロジェクトのeject
操作の後に限られます。
ほとんどの機能とそのアップデートはcreate-react-appシステムの内部に隠されています。あなたがeject
を作るなら、あなたはもういくつかの機能とその更新を持っていないでしょう。あなたがwebpackなどを設定するために含まれているアプリケーションを管理して設定する準備ができていないのであれば - eject
操作をしないでください。
既存の規則に従ってプレーしてください(srcに移動してください)。しかし今、あなたは制限を取り除く方法を知ることができます:do eject
そしてwebpack設定ファイルからModuleScopePlugin
を取り除きます。
create-react-appv0.4.0 なので、NODE_PATH
環境変数でパスを指定できます絶対輸入のため。
絶対インポートでは、変数import App from 'App'
で指定された値に対して相対的にimport App from './App'
の代わりにNODE_PATH
を使用することができます。
この機能はモノレポやその他の設定に関する質問には特に便利ですが、public
フォルダからの画像やその他のもののインポートには役立ちません。
public
フォルダーの内容はbuild
フォルダーに配置され、相対URLで使用可能になります。また、インポートされたものはすべてwebpackによって処理され、build
フォルダにも配置されます。
public
フォルダから何かをインポートすると、おそらくそのものがbuild
フォルダに複製され、2つの異なるURLで(または異なるロード方法で)使用可能になり、最終的にパッケージのダウンロードサイズが悪化します。
srcフォルダーからインポートするのが好ましく、利点があります。すべてのものはチャンク最適サイズおよびベストロード効率でwebpackによってバンドルにパックされます。
他人の答えにもう少し詳しい情報を提供する。 .pngファイルをユーザーに配信する方法に関して2つの選択肢があります。ファイル構造は、選択した方法に準拠している必要があります。 2つの選択肢があります。
React-create-appで提供されているモジュールシステム(import x from y
)を使用して、それをJSとバンドルしてください。 src
フォルダー内に画像を置きます。
public
フォルダからそれを提供し、Nodeにファイルを提供させます。 create-react-appも明らかに環境変数を持っています。 <img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
。これはReactアプリでそれを参照することはできますが、それでもNodeを通してそれを提供することができ、通常のGETリクエストであなたのブラウザがそれを別々に要求することを意味します。
パッケージ 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;
};
これにより、使用されているWebPackプラグインからModuleScopePluginが削除されますが、残りはそのままで、取り出す必要がなくなります。
WC-BlackonWhite.jpg
をあなたのsrc
ディレクトリに移動する必要があります。 public
ディレクトリはHTMLに直接リンクされる静的ファイル(faviconなど)用であり、バンドルに直接インポートするものではありません。
あなたの画像がパブリックフォルダにあるなら、あなたは使うべきです
"/images/logo_2016.png"
インポートする代わりに<img>
src
に含める
'../../public/images/logo_2016.png';
これはうまくいくでしょう
<img className="Header-logo" src="/images/logo_2016.png" alt="Logo" />
この制限により、すべてのファイルまたはモジュール(エクスポート)が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
を削除します。./node_modules/react-scripts/config/webpack.config.dev.js
からconst ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
をコメントまたは削除するシモンズ: eject の影響に注意してください。
最善の解決策はreact-scripts
をforkすることです。これは公式のドキュメントで実際に言及されています。 取り出しの代替方法
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()
]),
]
}
}
取り出す必要はありません。 rescripts library でreact-scripts
設定を変更できます
これはその後動作します:
module.exports = config => {
const scopePluginIndex = config.resolve.plugins.findIndex(
({ constructor }) => constructor && constructor.name === "ModuleScopePlugin"
);
config.resolve.plugins.splice(scopePluginIndex, 1);
return config;
};