[eggjs/egg]egg 不支持 Yarn 2

2024-03-29 238 views
1
What happens?

egg 在 Yarn 2 下无法运行

最小可复现仓库

https://github.com/duanzheng/test-egg-yarn-v2

复现步骤,错误日志以及相关配置
  1. 安装最新版的 Yarn,并按照官方教程开启 Yarn 2 模式
  2. 在项目根目录执行 yarn install
  3. 执行 yarn dev,此时会报错
    Error: egg is not found in /Users/tony/Documents/myCode/egg-test/node_modules
    at assertAndReturn (/Users/tony/Documents/myCode/egg-test/.yarn/cache/egg-utils-npm-2.4.1-a2af25016f-2.zip/node_modules/egg-utils/lib/framework.js:66:9)
    at Object.getFrameworkPath (/Users/tony/Documents/myCode/egg-test/.yarn/cache/egg-utils-npm-2.4.1-a2af25016f-2.zip/node_modules/egg-utils/lib/framework.js:49:10)
    at DevCommand.formatArgs (/Users/tony/Documents/myCode/egg-test/.yarn/cache/egg-bin-npm-4.14.1-b4aed5d5cd-2.zip/node_modules/egg-bin/lib/cmd/dev.js:89:28)
    at formatArgs.next (<anonymous>)
    at onFulfilled (/Users/tony/Documents/myCode/egg-test/.yarn/cache/co-npm-4.6.0-dd9caee4b9-2.zip/node_modules/co/index.js:65:19)
    at /Users/tony/Documents/myCode/egg-test/.yarn/cache/co-npm-4.6.0-dd9caee4b9-2.zip/node_modules/co/index.js:54:5
    at new Promise (<anonymous>)
    at co (/Users/tony/Documents/myCode/egg-test/.yarn/cache/co-npm-4.6.0-dd9caee4b9-2.zip/node_modules/co/index.js:50:10)
    at toPromise (/Users/tony/Documents/myCode/egg-test/.yarn/cache/co-npm-4.6.0-dd9caee4b9-2.zip/node_modules/co/index.js:118:63)
    at next (/Users/tony/Documents/myCode/egg-test/.yarn/cache/co-npm-4.6.0-dd9caee4b9-2.zip/node_modules/co/index.js:99:29)

看了一下报错的 egg-utils/lib/framework.js 的代码,代码中写死了会去找 node_modules 中的文件,然而 Yarn 2 默认是没有 node_modules 的,这个也是我们需要的新特性。

相关环境信息
  • 操作系统:macOS 10.15.4
  • Node 版本:12.16.2
  • Egg 版本:2.15.1

回答

0

这个寻址是 Node 的规范来着, yarn2 这个我不清楚是怎么玩的。

4

可以了解一下,Yarn 2 把依赖的包压缩后存放在 .yarn/cache 目录下,并且使得它们的体积小到可以直接上传到 git 中,这样的好处是代码拉下来无需执行 yarn install 就能运行,并且跑 CI 的时候因为不用再执行 yarn install,速度会快很多。

5

.yarn/cache 没有做软链到 node_modules? 那 Node 怎么识别的?

2

默认情况下会生成一个 .pnp.js 文件,代码中的引用通过它去查找; 我们后来发现 Yarn 2 也支持生成 node_modules 的模式,同时也能利用到项目中的缓存文件,我们最终选择了这种方式。

1

这样需要 hack node 的 require 才行吧?

5

根本原因是 egg-core 和 egg-utils 里面的 loader 直接对 node_modules 的路径寻址导致的,而没有使用封装好的 require 方法。所以无法兼容 yarn v2、pnpm 等对依赖结构的优化,在 monorepo 的场景下也会出现寻址出错的问题,这个问题需要从 load 机制上解决

2

mono repo场景怎么处理呢?