一直都觉得 npm 版本号没什么好注意的,直到今天掉到坑里了,爬了一下午才爬出来,特作此文,加深印象,提醒自己。
某日,用的好好的 Webpack 突然打出来的包某个 entry 不能用了,一直报错 Uncaught TypeError: Cannot read property 'call' of undefined
。代码一顿分析没找到原因,去 Webpack Issue 上搜了一把,还真有不少遇到相同问题的(7499、7425)。官方维护人员给出的反馈是暂未定位到具体原因,翻看了下面的反馈,有人指出使用 4.9.2
以上的版本都会有问题。
So,cnpm i -D webpack@4.9.2
尝试安装了 4.9.2
的版本,重新打包,问题不再重现,问题解决,提交新的 package.json,美滋滋。
But,还没安稳多久。同事 Kim 表示自己的项目打出来的包还是不正常。怎么会这样呢,我们俩的项目都是一样的,代码都是最新的。于是我重新打包了一次项目,没能重现。于是 rm -rf node_modules
,重新 cnpm i
,自信打包。
问题复现…What?!怎么会?包不都是一样的吗?笔者一顿猛删 node_modules,下载了各种 webpack 版本,各种 cnpm i
,发现打包时好时坏,怎么回事呢?这时一道灵光闪过,会不会是 node_modules 下的包版本不一致呢?仔细对比了同事的 node_modules 发现,他的 webpack 居然是 4.12.0
的!为什么呢?笔者突然想起来,package.json 里面的配置是:
1 | { |
请注意这个 ^
,罪魁祸首就是这个 ^
!它的含义是 不低于当前版本主版本号的最新版本
。也就是说,如果当前 webpack 最高版本 4.12.0 ,那么你的 ^4.9.0
会去下载 4.12.0,也就是当前的问题版本,而不是 4.9.0!这也解释了为什么我主动 cnpm i -D webpack@4.9.2
的时候打包正常,而删除 node_modules 重新打包就会出现问题,两种操作下下来的 webpack 版本不一致嘛!
问题定位出来后,我们修改了 package.json,在官方修复该问题之前先锁定版本号:
1 | { |
重新安装&打包,问题不再重现,bug fix!
附 npmjs 官网对语义化符号的说明 https://semver.npmjs.com/。