一次血的教训 记npm package-lock.json导致的腥风血雨

一、问题产生

一次偶然的机会,发现公司代码仓库中,sdk构建和reactjs构建仓库中居然有package-lock.json,这两个本该在编译时生成的文件,对于有强迫症的我,自然看不下去。于是果断一个MR,删除了这两个package-lock.json。以为自己做了好事的我还在沾沾自喜,殊不知这给我带来了2天苦逼的问题定位…

二、过程&解决

MR合入的当日,21.0主分支base仓构建失败,CIE大佬找到我,跟我说是前端base仓构建的问题,我心中一惊,立即翻看当天合入的MR,发现能影响构建的流程的只有我的那个删除package-lock.json的MR。先定下心,看一下给的报错日志:

npm ERR! Unexpected end of JSON input while parsing near '...l.com"}],"directories'

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/louyanping/.npm/_logs/2018-12-14T03_32_00_994Z-debug.log
louyanpingdeMacBook-Pro:cnpc_group_buying louyanping$

没错,没有其他任何报错信息,就只有这模糊的一句话。当时流水线紧急,没考虑详细,直接新建一个分支,恢复删除的package-lock.json。想想先保证构建流程,再考虑问题。
上库之后,出乎意料的是,还是出现了上述的报错信息。这时候我就意识到问题的严重性了。

前两天听CIE负责人说机器环境可能变动,为了排除打包机器环境变动的原因导致,通过mr上库时间,找出最后一次构建成功的Base仓,回归到该提交,并提交到一个新的分支进行构建。发现可以成功构建,这就排除了机器环境的问题。

结合CIE 前一天的构建流水线正常,上完库就出问题这一点来看,问题基本可以定位是有代码上库导致,再次检查了一下当天上库的MR,再次确认只有我改动了构建相关的流程后,确定了是我上库删除package-lock.json的原因。
那么现在问题来了。我上库的代码导致了问题,还原后也不行,问题可能出在哪里?

缓存,这是我脑海中第一个闪过去的词。我后面提交的package-lock.json,已经无法还原由于缺失package-lock.json的期间,构建流程中某些缓存的东西,换句话说,由于没有package-lock.json,构建机器在安装依赖包的时候,做了一些非常规流程,更新了之前缓存包中依赖包。于是想到解决方案,清除npm缓存。

在构建机器执行 npm cache clean --force ,清除之前下载的包缓存,重新编译,发现之前的错没有了,但是取而代之的是另外一个错。

03:06:13  ERROR in [at-loader] [31m./node_modules/@types/node/ts3.4/fs.d.ts[39m:5:45 
03:06:13      TS2304: [31mCannot find name 'bigint'.[39m
03:06:13  
03:06:13  ERROR in [at-loader] [31m./node_modules/@types/node/ts3.4/fs.d.ts[39m:9:18 
03:06:13      TS2304: [31mCannot find name 'bigint'.[39m
03:06:13  
03:06:13  ERROR in [at-loader] [31m./node_modules/@types/node/ts3.4/fs.d.ts[39m:10:18 
03:06:13      TS2304: [31mCannot find name 'bigint'.[39m
03:06:13  
03:06:13  ERROR in [at-loader] [31m./node_modules/@types/node/ts3.4/fs.d.ts[39m:11:18 
03:06:13      TS2304: [31mCannot find name 'bigint'.[39m
03:06:13  
03:06:13  ERROR in [at-loader] [31m./node_modules/@types/node/ts3.4/fs.d.ts[39m:12:22 
03:06:13      TS2304: [31mCannot find name 'bigint'.[39m
03:06:13  
03:06:13  ERROR in [at-loader] [31m./node_modules/@types/node/ts3.4/process.d.ts[39m:8:27 
03:06:13      TS2304: [31mCannot find name 'bigint'.[39m
03:06:13  
03:06:13  ERROR in [at-loader] [31m./node_modules/@types/node/ts3.4/util.d.ts[39m:6:56 
03:06:13      TS2304: [31mCannot find name 'BigInt64Array'.[39m
03:06:13  

证明我的想法是正确的!缓存导致了构建流程依赖包安装策略的变化,清除缓存后,依赖包安装策略变化,采用package.json中最新规定下载的包,但现在最新下载的包中的某些库和缓存中的库冲突了,导致了报错!

根据报错信息,定位到是jssdk中某个其他模块引用了TypeScript中的bigint新特性,直觉告诉我,这肯定是由于版本不兼容导致的。目前package.jsonTypeScript中的版本为3.0.2,于是果断上TypeScript官网,查找更新记录,发现bigint的特性是在3.2版本后才支持。于是升级TypeScript中的版本为3.8.3,再次构建,问题终于得到解决。

三、总结

提交上库MR后,长舒一口气。这件事情到这里是暂时解决了,但是提交了package-lock.json导致的问题居然这么严重,不禁令人背脊发凉。回顾一下整个问题的产生,过程如下:

  • 2020.01.21日 某个开发提交了package-lock.json 且该文件至今还没有其他提交
  • 在这8个月的时间内,前端依赖库大大小小更新了好几拨
  • 其实我们这段时间的构建,用的都是package-lock.json中指定的依赖缓存路径,即使我们升级了某些库的版本,用的还是缓存中的依赖路径,服务器并没有重新下载。比如这个例子中的‘某个库’,例如叫libA,在2020年1月的时候,是1.0.0版本,只需要typeScript 3.0.2既可以满足需求。但是在5月的时候,他升级了,变成了1.2.0,必须要typescript3.2.0,支持bigint的库才可以跑。然而由于库上存在package-lock.json,下载的库还是缓存中的1.0.0,在存在package-lock.json文件的情况下,构建流程不会有问题,因为大家都没变,所以库上的依赖根本没有更新!这无非是埋下了一颗定时炸弹,等着某个人去踩…
  • 那个人就是我。从我删掉了库上的package-lock.json之后,恶魔的闸门被打开,依赖不兼容的问题显现…

这事情告诉我们,package-lock.json维护的重要性。在查阅了相关资料后发现,其实package-lock.json是推荐上库的,可怕的咱们上库了,后续的版本升级,却没有同步提交package.lock.json。导致了依赖不兼容。

四、关于npm install流程详细概述

这里推荐一篇好文:https://mp.weixin.qq.com/s/5tmND0G_ZkYVR7Dmug0ugQ
只是粗略的看了一下,还没有时间详细学习,有时间会进行详细的学习再转载。

猜你喜欢

转载自blog.csdn.net/qq_29722281/article/details/108517149