在子位置运行时反应脚本父文件夹node_modules错误
Posted
技术标签:
【中文标题】在子位置运行时反应脚本父文件夹node_modules错误【英文标题】:react-scripts parent folder node_modules error when running in child location 【发布时间】:2020-03-22 05:07:29 【问题描述】:当在子文件夹 (c:\Repos\web_app1\api_ui)
中运行 react-scripts build (Create-React-App)
和它自己的 package.json
、node_modules
文件夹等时,我收到以下错误:
react-scripts build
There might be a problem with the project dependency tree.
It is likely not a bug in Create React App, but something you need to fix locally.
The react-scripts package provided by Create React App requires a dependency:
"babel-loader": "8.0.4"
Don't try to install it manually: your package manager does it automatically.
However, a different version of babel-loader was detected higher up in the tree:
c:\Repos\web_app1\node_modules\babel-loader (version: 7.1.4)
将父文件夹的 (c:\Repos\web_app1)
babel-loader 更新到 v8.0.4 不是一个选项,因为 web_app1
依赖于 babel-loader v7.1.4
不能删除 c:\Repos\web_app1 中的 node_modules。这是父应用程序,需要自己的node_modules
。
我的解决方法是将SKIP_PREFLIGHT_CHECK=true
添加到.env 文件中。这似乎是一个 hack,我想要另一个涉及通过预检检查构建的修复程序。
子文件夹(c:\Repos\web_app1\api_ui)
中的package-lock.json有正确的babel-loader版本(8.0.4),那为什么会去父文件夹呢?
在子文件夹中构建 react-scripts 时,有没有办法忽略父文件夹或更高的树 node_modules
?
【问题讨论】:
我也遇到了同样的问题,你解决了吗? 这能回答你的问题吗? react-script problem while having a node_module folder in the parent directory 【参考方案1】:这也让我很困惑,我做了一些研究,查看了react-scripts
版本4.0.3
的源代码。此版本需要babel-loader
v. 8.1.0
。安装了storybook
(需要版本^8.0.0
),我们在顶层node_modules
中得到一个不同的babel-loader
,因此我们最终得到:
|-src
|-node_modules
|
|-storybook 6.3.12
|-babel-loader 8.2.6
|-react-scripts 4.0.3
|
|-node_modules
|
|-babel-loader 8.1.0
我收到与很多人看到的相同的错误消息,我想我自己,不应该在react-scripts
中使用babel-loader
在它自己的babel-loader
中获得babel-loader
,即版本8.1.0
?我可以多次删除node_modules
和package-lock.json
,而且问题似乎一直存在。
您在问题中如何描述它实际上是包管理器(至少npm
)如何工作,例如从react-scripts
导入babel-loader
会从它自己的node_modules
给它版本8.1.0
...但是我们忘记了两件事,它们结合起来会导致问题:
吊装
我不会详细说明何时发生包裹提升,但它确实发生了。基本上,它相当于将依赖包A
的依赖包B
添加到项目根node_modules
(或其他一些父node_modules
),而不是添加到A
的node_modules
。
所以不是
|-src
|-node_modules
|
|-A
|
|-node_modules
|
|-B
...我们得到...
|-src
|-node_modules
|
|-A
|
|-node_modules (might exist anyway)
|-B
由于npm
的工作方式(并且正如您在问题中正确理解的那样),如果在node_modules/A/node_modules
中找不到B
,它将在node_modules
中查找包,这使得它可以工作。当许多包都需要兼容的依赖项时,提升可以是一种优化,这样我们就可以只存储一个,而不是存储 N 个相似版本的依赖项。它还简化了项目根目录node_modules
的文件夹结构,从而更易于调试。事实上,默认是吊起任何可以吊起的包,例如node_modules
中尚不存在要提升到的对象。
通常,每当我们有冲突的包版本时,都会使用“包的所有依赖项都在它自己的node_modules
”中的天真的策略。这就是上面例子中发生的情况,有两个不同版本的babel-loader
; storybook
确实由几个包组成,其中多个包使用babel-loader
版本^8.0.0
。当storybook
安装在react-scripts
之前时,它会采用满足约束的babel-loader
的最新版本,并将其提升到顶层node_modules
。这会在安装react-scripts
时导致常见的问题。我有另一个具有相同设置的项目,但是在storybook
之前安装了react-scripts
。在那里,babel-loader
版本 8.1.0
被吊起,并且由于这个包也满足 storybook
(^8.0.0
) 的要求,因此不再需要 babel-loader
。在这里,create-react-scripts
没有抱怨。当然,npm
可以自己计算出这个顺序当然是可取的,这从存储的角度来看也是最佳的(只有一个 babel-loader
而不是两个),但据我所知,npm
使用字母顺序时处理依赖关系。
传递依赖
尽管包 A
是我项目的依赖项,A
也可以拥有自己的依赖项。这些是关于我的项目的传递依赖项。
为什么它不起作用?
在react-script
版本4.0.3
的源代码中,文件verifyPackageTree
负责运行检查帽,导致问题中出现无聊的错误消息。这个文件在以后的预发布中不再存在,但在它的顶部,我们可以找到评论:
// We assume that having wrong versions of these
// in the tree will likely break your setup.
// This is a relatively low-effort way to find common issues.
下面几行写着:
// These are packages most likely to break in practice.
// See https://github.com/facebook/create-react-app/issues/1795 for reasons why.
// I have not included Babel here because plugins typically don't import Babel (so it's not affected).
查看引用的线程,讨论了为什么create-react-app
在安装不兼容的依赖项时会中断,问题与上述相同... 为什么不起作用?
最后的结论似乎是,例如,如果react-scripts
导入一个已被提升的包X
,则该包不会驻留在react-scripts
下的node_modules
中,而是位于根@ 987654389@,其中(相对于最上面的示例)还有babel-loader
版本8.2.6
驻留(与react-scripts
的node_modules
文件夹中的版本8.1.0
相对)。现在如果 X
要导入 babel-loader
,它会得到错误的 babel-loader
,例如不是预期的版本8.1.0
,而是8.2.6
。在线程中,这被认为是npm
中的一个错误,即使我不完全知道为什么它会是一个错误。也许,可能会有一些标志表明是否可以吊起一个包裹,因为如果完全吊装被认为是一个错误,这似乎是一种倒退。
因为create-react-app
的编写者不知道某些依赖项是否被提升,所以他们实现了这个简单的检查,它会抛出一个警告。对于高级用户,他们有机会使用SKIP_PREFLIGHT_CHECK
标志选择退出检查。另外,最好记住错误来自create-react-app
,而不是npm
,所以它实际上并没有说明npm
的工作原理,只是create-react-app
的创建者认为的问题(这是最初确实同样令人困惑)。
【讨论】:
以上是关于在子位置运行时反应脚本父文件夹node_modules错误的主要内容,如果未能解决你的问题,请参考以下文章
将 node_modules 文件夹移动到父文件夹并收到此错误
请问用C#编写的MDI程序,为啥我从父窗口通过按钮打开子窗口时,父窗口的按钮会在子窗口中显示?