Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于 pnpm8 依赖版本安装错误的问题 #50

Open
anyesu opened this issue Mar 31, 2024 · 0 comments
Open

关于 pnpm8 依赖版本安装错误的问题 #50

anyesu opened this issue Mar 31, 2024 · 0 comments

Comments

@anyesu
Copy link
Owner

anyesu commented Mar 31, 2024

背景


cover

创建完 Vue 3 版本的 Taro 项目,运行的时候发现报错了:

I:\Temp\taro-demo-vue3>npm run dev:h5

> taro-demo-vue3@1.0.0 dev:h5
> npm run build:h5 -- --watch


> taro-demo-vue3@1.0.0 build:h5
> taro build --type h5 --watch

👽 Taro v3.6.25

Tips:
1. 建议开启持久化缓存功能,能有效提升二次编译速度,详情请参考: https://docs.taro.zone/docs/config-detail#cache。


node:internal/modules/cjs/loader:1028
  const err = new Error(message);
              ^

Error: Cannot find module 'vue/compiler-sfc'
Require stack:
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\vue-loader@17.0.0_webpack@5.78.0\node_modules\vue-loader\dist\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+plugin-framework-vue3@3.6.25_@tarojs+runtime@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25_vue@3.0.0\node_modules\@tarojs\plugin-framework-vue3\dist\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+plugin-framework-vue3@3.6.25_@tarojs+runtime@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25_vue@3.0.0\node_modules\@tarojs\plugin-framework-vue3\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+service@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\service\dist\utils\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+service@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\service\dist\Kernel.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+service@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\service\dist\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+service@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\service\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+cli@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\cli\dist\cli.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+cli@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\cli\bin\taro
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1028:15)
    at Function.Module._load (node:internal/modules/cjs/loader:873:27)
    at Module.require (node:internal/modules/cjs/loader:1100:19)
    at require (node:internal/modules/cjs/helpers:119:18)
    at Object.<anonymous> (I:\Temp\taro-demo-vue3\node_modules\.pnpm\vue-loader@17.0.0_webpack@5.78.0\node_modules\vue-loader\dist\index.js:8:24)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
    at Object.newLoader [as .js] (I:\Temp\taro-demo-vue3\node_modules\.pnpm\pirates@4.0.6\node_modules\pirates\lib\index.js:121:7)
    at Module.load (node:internal/modules/cjs/loader:1076:32)
    at Function.Module._load (node:internal/modules/cjs/loader:911:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\[email protected][email protected]\\node_modules\\vue-loader\\dist\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]_@[email protected][email protected]\\node_modules\\@tarojs\\plugin-framework-vue3\\dist\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]_@[email protected][email protected]\\node_modules\\@tarojs\\plugin-framework-vue3\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]\\node_modules\\@tarojs\\service\\dist\\utils\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]\\node_modules\\@tarojs\\service\\dist\\Kernel.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]\\node_modules\\@tarojs\\service\\dist\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]\\node_modules\\@tarojs\\service\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]\\node_modules\\@tarojs\\cli\\dist\\cli.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]\\node_modules\\@tarojs\\cli\\bin\\taro'
  ]
}

问题定位


报错原因是 vue 包下找不到 compiler-sfc 这个目录,查一下 vue 的版本:

I:\Temp\taro-demo-vue3>pnpm ls vue
Legend: production dependency, optional only, dev only

taro-demo-vue3@1.0.0 I:\Temp\taro-demo-vue3

dependencies:
vue 3.0.0

package.json 中定义的版本是 "vue": "^3.0.0" 然而就直接安装了 3.0.0 版本,这就很不合逻辑。

node_modules 删了,改用 npm 重新安装依赖,发现安装的就是最新版的 vue 了:

> npx rimraf@5 -g node_modules
> npm i
> npm ls vue
taro-demo-vue3@1.0.0 I:\Temp\taro-demo-vue3
├─┬ @tarojs/plugin-framework-vue3@3.6.25
│ └── vue@3.4.21 deduped
├─┬ @tarojs/test-utils-vue3@0.1.1
│ └─┬ @vue/vue3-jest@29.2.6
│   └── vue@3.4.21 deduped
└─┬ vue@3.4.21
  └─┬ @vue/server-renderer@3.4.21
    └── vue@3.4.21 deduped

再次启动项目也不报错了,说明问题出在 pnpm 身上。

pnpm 官网搜索后发现原因了: pnpm 版本( v8.0.0v8.6.12 )中 resolution-mode 的默认值是 lowest-direct ,即 安装依赖的最低版本 。从 [email protected] 开始,已经回滚默认值为 highest 了,所以出错的只有部分用户。而我好巧不巧安装了修复前的最后一个版本 8.6.12 后就没更新过。

解决方法


1. 升级 vue-loader 到一个不会报错的版本,比如 ^17.1.0

2. 升级 vue3 到一个不会报错的版本,比如 ^3.2.13

3. 项目根目录添加一个 .npmrc 文件

强制下载最高版本,可以兼容所有版本的 pnpm ,就是有点碍眼。

resolution-mode=highest

4. 升级 pnpm 版本

下载 exe 的方式以后升级还得手动替换,还是用 npm 仓库安装更加省事、通用。

npm i -g @pnpm/exe

这里有一个小技巧:先用 npm 全局安装 pnpm ,再用 pnpm 套娃安装指定版本的自己:

pnpm i -g @pnpm/exe@8.7.0

利用 pnpm 全局缓存的特性就可以快速切换不同版本的 pnpm 了。

> where pnpm
C:\Users\xxx\AppData\Local\pnpm\pnpm
C:\Users\xxx\AppData\Local\pnpm\pnpm.CMD
D:\nodejs\node_global\pnpm
D:\nodejs\node_global\pnpm.cmd

可以看到其实安装了两个 pnpm ,只是 %PNPM_HOME% 目录处于 PATH 环境变量中靠前的位置( 如果不是这样的话,自己调整一下环境变量的顺序 ),优先级更高,所以里面的 pnpm 就是我们实际用到的那个。

总结:还是手动把 vue-loadervue 以及 pnpm 都升级掉,这样以后比较省事。

小插曲


测试升级 pnpm 后的效果时,发现原先的报错是没了,但又报新的错了:

I:\Temp\taro-demo-vue3>npm run dev:h5

> taro-demo-vue3@1.0.0 dev:h5 I:\Temp\taro-demo-vue3
> npm run build:h5 -- --watch


> taro-demo-vue3@1.0.0 build:h5 I:\Temp\taro-demo-vue3
> taro build --type h5 "--watch"

👽 Taro v3.6.25

Error: Cannot find module '@tarojs/binding-win32-x64-msvc'
Require stack:
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+binding@3.6.25\node_modules\@tarojs\binding\binding.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+cli@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\cli\dist\create\project.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+cli@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\cli\dist\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+cli@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\cli\index.js
- I:\Temp\taro-demo-vue3\config\index.ts
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+service@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\service\dist\Config.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+service@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\service\dist\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+service@3.6.25_@tarojs+shared@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\service\index.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+cli@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\cli\dist\cli.js
- I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+cli@3.6.25_@tarojs+taro@3.6.25\node_modules\@tarojs\cli\bin\taro
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:931:15)
    at Function.Module._load (internal/modules/cjs/loader.js:774:27)
    at Module.require (internal/modules/cjs/loader.js:1003:19)
    at require (internal/modules/cjs/helpers.js:107:18)
    at Object.<anonymous> (I:\Temp\taro-demo-vue3\node_modules\.pnpm\@tarojs+binding@3.6.25\node_modules\@tarojs\binding\binding.js:70:29)
    at Module._compile (internal/modules/cjs/loader.js:1114:14)
    at Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
    at Object.newLoader [as .js] (I:\Temp\taro-demo-vue3\node_modules\.pnpm\pirates@4.0.6\node_modules\pirates\lib\index.js:121:7)
    at Module.load (internal/modules/cjs/loader.js:979:32)
    at Function.Module._load (internal/modules/cjs/loader.js:819:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]\\node_modules\\@tarojs\\binding\\binding.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]\\node_modules\\@tarojs\\cli\\dist\\create\\project.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]\\node_modules\\@tarojs\\cli\\dist\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]\\node_modules\\@tarojs\\cli\\index.js',
    'I:\\Temp\\taro-demo-vue3\\config\\index.ts',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]\\node_modules\\@tarojs\\service\\dist\\Config.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]\\node_modules\\@tarojs\\service\\dist\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]_@[email protected]\\node_modules\\@tarojs\\service\\index.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]\\node_modules\\@tarojs\\cli\\dist\\cli.js',
    'I:\\Temp\\taro-demo-vue3\\node_modules\\.pnpm\\@[email protected]_@[email protected]\\node_modules\\@tarojs\\cli\\bin\\taro'
  ]
}
找不到插件依赖 "@tarojs/plugin-framework-react",请先在项目中安装,项目路径:I:\Temp\taro-demo-vue3

这个 @tarojs/binding-win32-x64-msvc 包是 @tarojs/binding 包中的 optionalDependencies (可选依赖项) 。按理说应该会根据运行的系统环境自动安装的,但是没安装下来。又是耽误时间去怀疑是不是 pnpm 升级导致本地缓存错乱或者不再自动安装 optionalDependencies 了。

最后仔细看了 @tarojs/binding-win32-x64-msvc 包的 package.json 才发现它是依赖 node16 的,而我在升级 pnpm 的时候因为操作生疏把它安装的 node16 也一并删掉了,就只剩一个原装的 node14 了,知道真相后也是挺无语的。

关联问题



转载请注明出处: https://github.com/anyesu/blog/issues/50

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant