编译事故 感觉前端依赖管理太不省心了 顺便问问有什么优秀解决方案

2022-08-05 16:24:36 +08:00
 rekulas

前端框架 vue3.1/element-ui
编译工具 npm/cnpm/pnpm

本人主业后端但也会做前端开发,昨天删除 node modules 后重新 install ,结果就出问题了,加载后发现报错
“export ‘createElementBlock‘ (imported as ‘_createElementBlock‘) was not found in ‘vue‘

google 了下发现都建议升级 vue 版本,于是升级到了 3.2 ,dev 调试下发现没什么大问题直接推了更新,由于担心远程缓存便把编译服务器 node modules 也清空,结果发布之后才发现出错,大体如下

vendor.3155b104.js:5 ReferenceError: tagsDialog is not defined
    at Proxy.<anonymous> (index.vue_vue_type_style_index_0_lang.921681d1.js:73:19169)
    at Xm (vendor.3155b104.js:5:4389)

跟同事讨论后怀疑可能是 <componentname ref="tagsDialog" > 这里的 tagsDialog 没定义新版 vue 不兼容导致的,解决方案是 const taggingDialog = ref();定义下。

我开始以为就几个变量,于是改改改。。。结果越改越多,这样改下去不知道啥时候能改完,生产环境版本也出问题同事催着急用,于是想着能不能降低 vue 版本试试先把生产环境编译出来用着,手动解决 createElementBlock, 于是在 node_modules/.vite/里复制了一大堆新版本的方法过来,最后还是放弃了,因为依赖太多,手动兼容太费时间了。

于是情况就变成了,线上线下都无法编译出可用版本,dev 调试却没事,同事急着用。。。我都打算先本地跑个 dev 版本反代到生产环境先撑着再来修改,不过还好后面发现备份服务器上还有个备份,才暂时先跑起了。

感觉最近几年前端开发确实越来越便捷,但是依赖始终是个大问题,我同事更加精通前端开发几乎媲美比较专业的前端开发工程师了,但是之前打包 electron 也遇到更新后再也无法编译的问题,后面分析可能是某个组件的依赖更新了导致另一个依赖出了问题。相比起以前简陋的 jq ,虽然现在的眼光看起来很 low ,但很少遇到这样的问题,一个大项目点击即可运行,真正做到了所开发即所得,而现在我 dev 和编译的居然都不一样。。。

感觉今天的问题可能是我自己的项目 a ,依赖了组件 b ,我当然可以强行指定 b 的特定版本,但 b 也可能依赖了 c 而且 c 没限定版本的话。。。谁敢保证更新后不出问题呢?更何况 c 还有可能依赖 d 。。。

回归正题,我不想升级 vue 版本的话,有没有办法强行限定所有依赖的版本进行依赖安装?

2439 次点击
所在节点    前端开发
18 条回复
rekulas
2022-08-05 16:28:19 +08:00
网上搜索到 shrinkwrap 和 yarn 似乎可以锁定,我试试,虽然我不太喜欢 yarn ,感觉是个临时方案
rekulas
2022-08-05 16:39:37 +08:00
package-lock.json 共享的话,能否锁定所有依赖版本呢
isbase
2022-08-05 17:29:36 +08:00
简单点 yarn 就行。想更快就 pnpm
isbase
2022-08-05 17:30:15 +08:00
@rekulas 当然能锁定。
rekulas
2022-08-05 17:45:14 +08:00
@isbase 测试了下 lock.json 应该不行,准备尝试下 shrinkwrap
MorningStar0
2022-08-05 22:36:05 +08:00
@rekulas 这个没有锁定的话,应该是 package.json 中的依赖有 `^`这样的版本前缀
MorningStar0
2022-08-05 22:36:33 +08:00
@MorningStar0 导致和预期锁定的版本有偏差
rekulas
2022-08-05 23:02:45 +08:00
@MorningStar0 去掉了也不行,如我上面说的,导致问题的不是依赖的版本,而是依赖的依赖的版本,这个光靠 lock 似乎不行,不然就无法解释我光删除 node modules 为什么会导致问题了
CrazyMonkeyV
2022-08-10 11:31:19 +08:00
本身依赖的版本就应该锁定。后端的引用,版本也是锁定的
rekulas
2022-08-10 12:03:41 +08:00
@CrazyMonkeyV 对,应该锁定但实际上并没有,包括 npm 自身发布的一些项目也是默认更新依赖的,官方也并没有重视或让用户重视这个问题,而可见的开源项目大多数都是采用默认自动更新小版本的方式发布,这就给项目可靠性带来了风险问题,大多数时候这是没有问题的,但一旦遇到问题而你没有做版本备份的话-这会让你很头疼
hispy
2022-08-10 15:41:10 +08:00
lock 文件了解下
vishun
2022-08-10 16:08:27 +08:00
`lock`只能锁大版本,但是谁能保证小版本的更新就不会有兼容问题呢?用`npm ci`比较靠谱点。
rekulas
2022-08-10 16:24:26 +08:00
@hispy
@vishun
vishun 说的对,lock 并没有让我避免事故,因为我只是删除了 node_modules 没动 lock 的情况也翻车了
后续复盘发现,我之前 vue 版本应该是 3.1.5 ,自动更新到 3.2.37 出事故,回滚 3.1.5 也不行,但中间有个版本 3.2.15 是正常的,现在我通过 shrinkwrap 进行了锁定,目前看似乎正常
很莫名其妙,lock 没啥用,起作用的居然是一个号称即将废弃的功能
rekulas
2022-08-10 16:28:28 +08:00
其实理论上来说,随小版本自动更新才应该是最佳开发姿势,但实际情况下由于依赖三方包太多,没有办法确保所有的依赖更新都向下兼容 /不引起 bug 也不可能一个个去排查,所以有时候可能需要锁定一个稳定版在有必要的时候手动去更新再更新稳定版版本
wx497657341
2022-08-10 17:35:36 +08:00
根本原因是前端随随便便就出一个第三方包,而开发包的人没有按照规范制定版本号规范
https://semver.org/
rpman
2022-08-11 19:57:12 +08:00
依赖多了就老老实实 lock 版本
别搞什么 upstream first, 那是装逼用的
sugars
2022-08-26 16:00:56 +08:00
@wx497657341 没错,有些可能只是做了点小改动,直接从 1.0.0 升级成 2.0.0 也是存在的吧?
yushare89757
2022-09-22 09:54:28 +08:00
如果有 lockfile ,可以试试 npm ci

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/870920

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX