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

背景


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\\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'
  ]
}

问题定位


报错原因是 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 ,即 安装依赖的最低版本 。从 pnpm@8.7.0 开始,已经回滚默认值为 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\\@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'
  ]
}
找不到插件依赖 "@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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容