代码没改,重装了依赖就报错【已解决】

317 阅读2分钟

问题现象

前端开发中常常会遇到类似这样的问题:

  1. 代码没改,重装一下了依赖就报错了。
  2. 代码一样的,我本地报错,团队其他人不报错。

原因分析

这很可能是依赖出了问题,根因是package.json中指定依赖时可以范围性的指定,类似下面这样:

{
  "dependencies": {
    "foo": "1.0.0 - 2.9999.9999",
    "bar": ">=1.0.2 <2.1.2",
    "baz": ">1.0.2 <=2.3.4",
    "boo": "^version",
    "qux": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
    "asd": "<http://asdf.com/asdf.tar.gz>",
    "til": "~1.2",
    "elf": "~1.2.3",
    "two": "2.x",
    "thr": "3.3.x",
    "lat": "latest",
    "dyl": "file:../dyl"
  }
}

官方的说明如下

docs.npmjs.com/cli/v10/con…

version Must match version exactly

>version Must be greater than version

>=version etc

<version

<=version

~version "Approximately equivalent to version" See semver

^version "Compatible with version" See semver

1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0

那么,可能当时你的某一个依赖写成^version 没有问题,但随着这个依赖包的更新,可能作者只动了小版本号,但确引入了破坏性更新,就会对你造成影响。毕竟代码是人写的,版本号也是人定的,总会有考虑不到的地方。

这样,问题的现象就很好解释了:

  1. 你重新安装了依赖,在你上一次安装依赖和本次安装之间,作者更新了版本。
  2. 你的队友没有重新安装依赖。

**注意:**因为npm的依赖是层层嵌套的,所以有可能直接依赖的包没有问题,但是你依赖的依赖可能会有这样的问题,最终问题会传导到你的项目里。

解决办法

现象

下面举一个实例,现象是一个Electron应用,打包后运行出错:

image.png

排查

在项目中全局查了一下,发现项目并没有使用的到unused-filename这个包,从上图中的异常栈中其实也可以看到,是electron-dl这个包引用了它。

  1. 第一步,我把electron-dl的版本固定下来:"electron-dl": "^3.5.2""electron-dl": "3.5.2" 发现依旧报错,说明大概率不是electron-dl 版本更新导致的,它也是被坑了。

再在node_modules 中找到electron-dl 这个依赖,直接修改它的package.json

image.png

  1. 可以看到它引用了unused-filename,并且没有固定版本号,我们直接修改一下。"unused-filename": "^2.1.0”"unused-filename": "2.1.0”
  2. 再次打包,问题不存在了。

解决

问题找到了,但这是本地的打包,我们可以直接修改node_modules 中的文件。如果你用了CI/DI工具,为了改node_modules 中的文件而定制构建脚本,绝对是下下策。

此时只要把package-lock.json用好就行,把package-lock.json 也加入到git的版本控制中是一个好的习惯,package-lock.json 会固定好依赖以及依赖的依赖,如下:

image.png

image.png

这样,你就不需要改node_modules 中的文件了,在package-lock.json 中改就行。

package-lock.json 会在第一次npm i 时自动生成,把依赖以及依赖的依赖的版本固定下来,后续安装再多次也是使用你第一次的所有版本。

但需要注意的是 cnpm i 不会生成 package-lock.json,即使现在目录里有 package-lock.json 它也不会使用。