我正在使用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开发人员添加的特殊限制。这是在实施ModuleScopePlugin
,以确保文件驻留在src/
。该插件可确保从应用程序源目录的相对导入不会到达该目录的外部。
您可以通过eject
运行create-react-app项目来禁用此功能(方法之一)。
大多数功能及其更新都隐藏在create-react-app系统的内部。如果您这样做eject
,将不再具有某些功能及其更新。因此,如果您还没有准备好管理和配置用于配置Webpack等的应用程序-请勿执行eject
操作。
按照现有规则播放(移至src)。但现在你可以知道如何删除限制:做eject
和删除ModuleScopePlugin
从的WebPack配置文件。
有中间方案,即再布线系统,它允许您以编程方式修改没有的WebPack配置eject
。但除去该ModuleScopePlugin
插件是不是一个很好的-这个失去了一些保护,不增加了一些功能可用src
。
更好的方法是添加完全可用的类似于的其他目录src
。这可以使用react-app-rewire-alias完成
不要从public
文件夹导入-这将在build
文件夹中重复,并且可以通过两个不同的url(或以不同的加载方式)使用,这最终会使软件包下载大小变大。
从src
文件夹导入是可取的并且具有优点。一切将通过webpack打包到捆绑包中,并具有最佳大小和最佳装载效率。
软件包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,但其余部分保持不变,并消除弹出的必要性。
如果图像位于公用文件夹中,则应使用
"/images/logo_2016.png"
在您<img>
src
而不是导入
'../../public/images/logo_2016.png';
这会工作
<img className="Header-logo" src="/images/logo_2016.png" alt="Logo" />
为他人的答案提供更多信息。关于如何将.png文件交付给用户,您有两个选择。文件结构应符合您选择的方法。这两个选项是:
-
使用
import x from y
react-create-app随附的模块系统()并将其与JS捆绑在一起。将图像放在src
文件夹内。 -
从
public
文件夹提供服务,然后让Node提供文件。create-react-app显然还带有环境变量,例如<img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
。这意味着您可以在React应用程序中引用它,但仍然可以通过Node来提供它,而浏览器会在常规GET请求中单独要求它。
资料来源:create-react-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中链接的静态文件(例如favicon),而不是要直接导入捆绑包中的内容。
有一些答案可以为提供解决方案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()
我认为Lukas Bach解决方案使用react-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;
};
安装这两个软件包
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 = 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:当心弹出的后果。
您不需要弹出,可以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;
};
公用文件夹中的图像
use image inside html extension
<img src="%PUBLIC_URL%/resumepic.png"/>
use image inside js extension
<img src={process.env.PUBLIC_URL+"/resumepic.png"}/>
- 在js Extension中使用图片
如果只需要导入一个文件,例如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()
]),
]
}
}
最好的解决方案是fork react-scripts
,实际上在官方文档中提到过,请参阅:弹出的替代方法
如果您需要进行多种修改(例如使用ant design时),则可以将多种功能组合如下:
const {
override,
removeModuleScopePlugin,
fixBabelImports,
} = require('customize-cra');
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: 'css',
}),
removeModuleScopePlugin(),
);
除Bartek Maciejiczek的答案外,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;
}
}
};
您可以尝试使用simlink,但是相反。
React不会遵循simlink,但是您可以将某些内容移至源目录,并为其创建simlink。
在项目的根目录中,我有一个节点服务器目录,其中包含多个架构文件。我想在前端使用它们,所以我:
- 移动文件/ src
- 在术语中,我确定了模式文件在服务器中的位置
ln -s SRC_PATH_OF_SCHEMA_FILE
这样就可以响应所需的内容,并且节点非常高兴通过simlinks包含文件。
文章标签:create-react-app , javascript , reactjs , webpack
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!