由线上bug引发的关于node_modules的思考

737 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

前言

最近一段时间,公司发生了几起比较严重的事故,以致于看领导的眼光都是慢慢的担心和愧疚,更不用想升职加薪了。经过几番艰苦的排查攻坚战,最终找到了事故的源头,就是第三方依赖

node_modules的爬坑之旅

不给力的package.json


经常开发的小伙伴们,肯定都知道每一个第三方依赖都有版本号,由低到高依次递进。版本号又是由三部分组成:主版本、次版本、补丁版本。通常我们安装一个依赖,绝大多数的版本号是这样的 ^4.2.0,极少数的版本号是这样的 ~5.4.0,基本没有版本号是这样的 3.0.0

~ 是锁定次版本的意思,比方说,某个依赖的版本号是 ~5.4.0,那么每次安装依赖的时候都会安装 5.4.x 中最新的版本。

^ 是锁定主版本的意思,比方说,某个依赖的版本号是 ^4.2.0,那么每次安装依赖的时候都会安装 4.x.x 中最新的版本。

这就很苦逼了,由于配置了自动化部署,每次触发构建部署的时候,都会重新安装一下依赖。这时一个很恶心的问题就产生了:明明我在本地开发的时候还好好的,为啥一发到灰度或者线上环境就会有问题呢?

这其实就是node_modules依赖版本的默认管理机制导致的。

苦逼的锁定版本


最开始直接就采用了锁版本的方案,现在想想,当年还是太年轻了。

image.png

表面上来看是解决问题了,但是,一切都是假象。平静了一段时间就出现了新的问题。

lock出马


上一个方案还是没有办法锁定住依赖的版本。打个不恰当的比喻,在node进行模块化管理的开发中,就跟俄罗斯套娃一样,你依赖第三方依赖,第三方依赖依赖其它的第三方依赖,直到最终的所有的依赖都出现在了项目中为止。

看到这里,应该就恍然明白了为什么单纯的锁住package.json中的版本号是治标不治本的吧。虽然很透了,但是我还是要提一下原因:那就是第三方依赖的版本没有锁定。

也正是由于这个原因,yarn和npm相继推出了 yarn.lockpackage-lock.json。通过lock文件可以将项目中的依赖锁定,这样就可以保证安装的依赖的一致性。

image.png

我也采用了这个方案,确实舒爽哈,好一段时间都风平浪静的。直到某一天,我碰到了那个他。在这一天,忽然构建部署失败了,迫于大家的压力,我苦哈哈了半天终于找到了问题的原因:原来是我们的一个小伙伴把他本地的lock文件给上传到仓库了。

我也是吐了,说好的yyds的呢。

终极大招


最后经过内部几轮的论证讨论,我们决定推出我们自己的依赖管理平台——对所有项目中的版本依赖进行集中管控。通过依赖管理平台对项目的所有依赖进行版本的管控和node_modules的统一处理,这样就可以保证团队的每个成员的依赖的统一,线上、灰度和本地环境的依赖的统一。

由于牵涉到保密协议,这里就不细讲了,只说一下大体的解决方案:在依赖管理平台新增或者更新依赖之后,通过云端进行依赖安装,将node_modules统一管控在云端,然后通过内部实现的脚手架来保证本地开发、构建部署都采用云端依赖。

结语

好了,希望以上内容对大家的日常开发有所帮助。同时也希望大佬有更好的方案,让我打开眼界。