blog
blog copied to clipboard
npm workspaces 问题解决
在npm workspaces 踩坑记录中,我最终使用了 yarn v1 来解决依赖无法安装的问题,但在用了几天 yarn v1 之后,发现它对 workspaces 的支持还是比较少的,而且也有一些问题(比如这个),但我又实在不想用 yarn v2,于是我又来想办法切换回 npm 了。
先说结论:我最终使用 @hcfy/react-shadow 替换了 react-shadow。
一开始我是不想单独创建一个包的,我还是寄希望于 npm 新增的 overrides,但最终只有创建一个新包才能解决问题,在此记录一下踩坑过程。
我先是删掉了 yarn.lock 和 node_modules,然后运行了 npm i
,报错如下:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR! react@"^18.2.0" from [email protected]
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0 || ^17.0.0" from [email protected]
npm ERR! node_modules/react-shadow
npm ERR! react-shadow@"^19.0.2" from [email protected]
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
在上一篇文章当中,我已经提到过 --force
和 --legacy-peer-deps
都不能解决我的问题,这一次我打算从出问题的包(也就是 react-shadow)入手。
我先是将 package.json 里的 react-shadow 删掉,然后 npm i
就可以正常运行了。
然后,我尝试运行了 npm i react-shadow
,出现了同样的报错。
在 package.json 里添加了 overrides
还是报同样的错误:
{
"overrides": {
"react": "$react"
}
}
改成下面这样也还是报同样的错:
{
"overrides": {
"react-shadow": {
"react": "18.2.0"
}
}
}
尝试运行 npm i --force react-shadow
是能成功,但还是会出现上一篇文章里提到的两个 react 版本的问题。
于是最终没办法,还是只能 fork 了 react-shadow,然后按照这条 PR 的内容将 react 18 加入进了 peer deps,最终运行 npm i @hcfy/react-shadow
成功了。
升级到 react 18 理论上对 react-shadow 没有影响。
切换为 npm 之后出现了另一个问题,是关于 node-fetch 的。
同样由于依赖的版本不一致,导致根目录下的 node_modules/node-fetch 是 v2,但是 packages/app/node_modules/node-fetch 是 v3。这本来没什么,但是运行项目的时候发现 node-fetch v3 报错了,说是找不到模块 data-uri-to-buffer
查了一下,data-uri-to-buffer 是 node-fetch v3 依赖的三个模块之一,但是用 npm why data-uri-to-buffer
发现 npm 压根就没有安装这个模块……看来又是个 bug。
目前来看只能我自己安装这个模块了,虽然我觉得这不应该是由我安装进自己项目的 package.json 的,但也没别的办法了。
我本来想把这个模块安装进 packages/app 里,但一不小心安装在了根目录,于是用 npm un data-uri-to-buffer
删除了,但是此时我又运行了一下 npm why data-uri-to-buffer
发现这个模块还是在的,且能正确识别出它是被 node-fetch v3 依赖的,于是我又运行 npm i fetch-blob && npm un fetch-blob
这样把 node-fetch v3 的三个依赖全这么安装了一下,然后再运行项目就一切正常了 :joy:
以后再遇到 npm 没有正确安装依赖的情况可以用这个方法试一下。
今天又发现了这个方法的一个用处:改变 node_modules 目录结构
今天把 workspace 里的所有 eventemitter3 从 4.0.7 升级到了 5.0.0,然后用 npm why eventemitter3
看了一下,发现项目里有五个 eventemitter3,其中 ./node_modules/eventemitter3
里的是 4.0.7,而剩下的都是 5.0.0,都在 packages 目录下(即 ./packages/<项目名称>/node_modules/eventemitter3
)。
检查了一下,发现是其中一个 package 有一个 devDep 依赖的是 eventemitter3 v4.0.7,而由于 ./node_modules/eventemitter3
里的原本就是 4.0.7,所以 npm 把 5.0.0 分别安装在了每个 packages 里。
但是由于只有这一个 package 依赖的是 4.0.7,所以我想反过来,即我希望 ./node_modules/eventemitter3
里的是 5.0.0,然后只有 ./packages/<依赖 4.0.7 的 package>/node_modules/eventemitter3
里的是 4.0.7。
尝试了用 npm ddp
无效,然后试了下 npm i eventemitter3 && npm un eventemitter3
就成功改变成了我想要的目录结构。
出现这个问题的 npm 版本是 8.19.2,我特意升级到了最新版 9.1.2 试了下,这个 bug 没有解决;同时也使用这个版本试了一下 overrides,同样没用 :joy: