src 目录之外的 create-react-app 导入限制

IT技术 javascript reactjs webpack create-react-app
2021-01-19 00:22:07

我正在使用 create-react-app。我正在尝试从我的src/components. 我收到此错误消息。

./src/components/website_index.js 未找到module:您试图导入 ../../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" />

我读过很多东西说你可以对路径进行导入,但这对我来说仍然不起作用。任何帮助将不胜感激。我知道有很多这样的问题,但它们都告诉我要导入徽标或图像,所以很明显我在大局中遗漏了一些东西。

6个回答

这是 create-react-app 的开发者添加的特殊限制。它被实现ModuleScopePlugin以确保文件驻留在src/. 该插件确保来自应用程序源目录的相对导入不会到达它之外。

除了使用eject和修改 webpack 配置外,没有官方方法可以禁用此功能

但是,大多数功能及其更新都隐藏在 create-react-app 系统的内部。如果您制作,eject您将不再有新功能及其更新。所以如果你还没有准备好管理和配置包含的应用程序来配置 webpack 等等 - 不要做eject操作。

按照现有规则进行操作 - 将资产移动到 src 或根据public文件夹 url 使用而无需导入。


但是不是eject也有很多非官方的解决方案的基础上, 再布线,让您以编程方式修改没有的WebPack配置eject除去ModuleScopePlugin插件并不好-这失去了一些保护,不添加了一些功能可用srcModuleScopePlugin旨在支持多个文件夹。

更好的方法是添加完全工作的附加目录,类似于src也受ModuleScopePlugin. 这可以使用react-app-rewire-alias来完成


无论如何不要从public文件夹导入- 这将在build文件夹中复制,并且可以通过两个不同的 url(以及不同的加载方式)使用,这最终会恶化包下载的大小。

src文件夹导入是可取的,并且具有优势。一切都将由 webpack 打包到具有最佳大小的最佳加载效率的包中

@VP 但错误说“从项目的 node_modules/ 添加符号链接到它。”,这不起作用吗?
2021-03-12 00:22:07
这是如何被接受的答案?只需NODE_PATH=./src/...env文件中设置即可轻松消除这种虚假限制通过这样做,您可以从 src 文件夹外部导入,而无需经历与弹出应用程序相关的痛苦。
2021-03-12 00:22:07
如果您在 ./src 中创建符号链接,并从那里导入 - 构建不起作用(babel 插件不会转换符号链接文件夹中的源)。因此,有了这个限制,在 src 下并且没有符号链接,您实际上被置于“无共享代码与其他项目”监狱中(除非您选择完全移出/退出 CRA)
2021-03-30 00:22:07
看起来 baseUrl 不再有效。任何将其设置在源树错误之外的尝试:您的项目baseUrl只能设置为srcnode_modulesCreate React App 目前不支持其他值。@Flaom 预先准备的技巧./src也无济于事。
2021-04-04 00:22:07
@adrianmc。从项目的 node_modules 添加符号链接不起作用,因为许多项目使用不是 node_modules 的共享组件/代码。例如,我在 React Native 和 React Native Web 之间共享代码。那些“片段”不是 node_modules,这两个项目实际上有不同的 node_modules。
2021-04-08 00:22:07

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,但保留其余部分并消除弹出的必要性。

@bijayshrestha 阅读 react-app-rewired 项目的自述文件,它解释了如何设置它。在安装过程中,您将创建一个config-overrides.js文件,您可以在其中放置代码。
2021-03-17 00:22:07
你能确认我应该把这个代码片段放在哪里吗?
2021-03-23 00:22:07
很好的答案。您可以react-app-rewired通过 [ github.com/arackaf/customize-cra](customize-cra)进一步利用然后配置将使用 justbabelInclude([path.resolve('src'), path.resolve('../common')])removeModuleScopePlugin()
2021-03-24 00:22:07
此解决方案是否适用于 Typescript?我无法让它与 TS 一起使用。
2021-04-01 00:22:07
删除ModuleScopePlugin插件不是一个好主意。最好添加类似于src使用react-app-rewire-alias 的完全可用的附加目录
2021-04-08 00:22:07

如果您的图像在公共文件夹中,那么您应该使用

"/images/logo_2016.png"

在你<img> src而不是进口

'../../public/images/logo_2016.png'; 

这将工作

<img className="Header-logo" src="/images/logo_2016.png" alt="Logo" />
不为我工作。得到相同的消息 - '在项目 src/ 目录之外。不支持 src/ 之外的相对导入。
2021-03-14 00:22:07
这正是我要找的!我只是在我的 CRA 的“src”目录中添加了一个“images”文件夹,然后我就可以使用了<img src="/images/logo.png" alt="Logo" />
2021-04-03 00:22:07
@Arkady 您的照片可能仍然有导入声明。删除该导入语句,只需在 src 属性中提供直接路径。
2021-04-06 00:22:07
您的回答是正确的 IMO,但我冒昧地澄清您说的是 中的路径<img src="...">,而不是导入它
2021-04-10 00:22:07

使用 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;
    }
  }
};
接受了这个答案,并将它与这个 gitlab 评论结合起来,让它在 Typescript 上工作。完整的解决方案作为自己的答案
2021-03-11 00:22:07
@panepeter - 您的解决方案“有效”,但我在导入钩子时遇到问题,react 抱怨臭名昭著的“错误:钩子调用无效。钩子只能在函数组件的主体内部调用。” 我需要进一步调查...
2021-03-15 00:22:07
为了让它与 TypeScript 一起工作,我需要这个答案和 MikeW 发布的链接。
2021-03-26 00:22:07
与这个stackoverflow.com/a/58603207/2987400结合使用效果很好
2021-04-06 00:22:07
为克拉科投票!Craco 支持 CRA 3.x
2021-04-10 00:22:07

为其他人的答案提供更多信息。关于如何将 .png 文件交付给用户,您有两种选择。文件结构应符合您选择的方法。这两个选项是:

  1. 使用import x from yreact-create-app 提供的module系统 ( ) 并将其与您的 JS 捆绑在一起。将图像放在src文件夹中。

  2. public文件夹中提供,让 Node 提供文件。create-react-app 显然也带有一个环境变量,例如<img src={process.env.PUBLIC_URL + '/img/logo.png'} />;. 这意味着你可以在你的 React 应用程序中引用它,但仍然通过 Node 提供它,你的浏览器在普通的 GET 请求中单独请求它。

来源:创建react应用程序

建议#2 正是导致我出现以下错误的原因:未找到module:您试图导入 ./../../../public/CheersBar-Drinks-147.jpg,它位于项目 src/ 目录之外. 不支持 src/ 之外的相对导入。您可以将其移动到 src/ 中,也可以从项目的 node_modules/ 中向其添加符号链接。
2021-03-21 00:22:07