重新install,项目就跑不起来了?!

现象:重新install失败

打包平台执行命令:npm run reinstall

shell 复制代码
{
    "bootstrap": "pnpm install",
    "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap"
}

产生报错:

原因探索:pnpm依赖的依赖,版本更新造成了问题

自动化编译平台的日志,对比历史编译记录,发现esbuild的版本号变了,但是我们自己项目里的package.json没有引用过esbuild

观察lock文件和源码,发现是esno@0.14.1引用了esbuild

这样在重新install的时候,esbuild更新到当时最新的0.27.1版本,导致了报错。

处理方法探索:

为什么不能使用 patch 修改依赖源码

相关文章:如何优雅地修改node_modules里依赖的源码?

我们想当然地认为,使用 pnpm patch去修改源码,把 "esbuild": ">=0.13.0"改成锁定版本的"esbuild": "0.14.27"就能解决问题,实际上这种场景不适用pnpm patch

pnpm patch,修改源码时,不会等esno安装好再去安装esbuild,下图是没有pnpm-lock.yaml文件的时候使用patch命令报的错。

No pnpm-lock.yaml found: Cannot patch without a lockfile

pnpm patch只能去修改源码,在项目运行阶段生效,而package.json文件并不算源码,我们希望在install阶段处理。

peerDependencies,描述项目对某些依赖的共存期望

我在esbuild-register中也发现了esbuilddependenciespeerDependencies都有,但实际安装的依赖里,并没有esbuild@0.14.8

peerDependencies的主要作用是表示项目需要一个特定版本的依赖项,但并不主动去安装它,而是将安装这个依赖的责任交给最终的使用者。

因此,如果esno里也定义peerDependencies,我们就能在自己的主项目中定义esbuild的版本号并锁定了。

上面两种方案,都可以通过重新推送npm包的方式解决。相关文章:手把手教你如何配置私有npm库。处理方式:fork一下esno,并改个名字,然后修改package.json,无论是修改esbuild的版本号,还是添加peerDependencies,都可以解决我们的问题。修改完成之后,上传到公司的私有库上即可使用。

更简单的方案:overrides,强制重写依赖

json 复制代码
"pnpm": {
  "overrides": {
    "esbuild": "0.14.27"
   }
}

设置后,所有标记为该版本可用的依赖,都会使用我们指定的这个版本。

优化打包平台

直接检测 pnpm-lock.yaml有没有更新,如果有,就reinstall(pnpm-lock.yaml不删)。

shell 复制代码
{
  "reinstall": "rimraf node_modules && npm run bootstrap",
}

如果pnpm-lock.yaml文件有改动,就删除node_modules目录重新install。原来的reinstall是删掉了pnpm-lock.yaml的,导致install的时候都按照package.json把版本都升级了,导致意外的问题。

Jenkins配置:代码提交时如果有pnpm-lock.yaml,就执行reinstall命令,根据提交的pnpm-lock.yaml文件取安装依赖。

shell 复制代码
git diff --name-only $GIT_PREVIOUS_COMMIT $GIT_COMMIT | grep pnpm-lock.yaml && npm run reinstall
npm run build

其他问题处理:在一个项目里同时引用两个不同版本的依赖

设置别名:

json 复制代码
"dependencies": {
  "echarts": "^4.8.0",
  "echarts-latest": "npm:echarts@^6.0.0"
}

总结

npm 官方文档明确建议:"always commit your package-lock.json"。yarn 和 pnpm 同样要求提交各自的锁文件(yarn.lockpnpm-lock.yaml),这个对团队协作保持环境统一有重要意义。非必要情况下,我们尽量不会自动更新依赖的版本并且直接打包部署,避免出现意外的问题。

相关推荐
codeGoogle5 小时前
自研 IM 还是选择第三方 SDK?企业开发者应该如何权衡?
前端·后端·程序员
用户938515635076 小时前
React Context 与自定义 Hook 从底层到实践:「跨层级通信 + 副作用封装」全解析
前端·javascript·react.js
滴滴答答哒6 小时前
VUE3+element-plus MultiSelect 多选下拉组件
前端·javascript·vue.js
其美杰布-富贵-李7 小时前
04 watch 与 Vue 响应式数据流
前端·javascript·vue.js
赵大仁8 小时前
生成式 UI 实战:用 JSON Schema + React 动态渲染 AI 界面
前端·ai·react·next.js·前端架构·生成式ui
kyriewen9 小时前
我排查了一个React内存泄漏——罪魁祸首是这3个被忽略的清理函数
前端·javascript·面试
IT_陈寒9 小时前
我又被JavaScript的隐式类型转换坑了
前端·人工智能·后端
其美杰布-富贵-李10 小时前
03 ref、reactive 与 computed 响应式数据
前端·javascript·vue.js
OpenTiny社区10 小时前
GenUI SDK v1.3.0 发布|多框架兼容,一键换物料,渲染器 & 演练场全面增强!
前端·ai编程
用户9385156350710 小时前
useRef + Web Worker 实战:React 如何优雅地拥抱多线程
前端·javascript·react.js