0
点赞
收藏
分享

微信扫一扫

为什么有了package.json还需要package-lock.json

禾木瞎写 2022-04-19 阅读 54
node.jsnpm

在执行npm init的时候,项目中会生成package.json文件。

{
  "name": "test-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/react": "^16.14.14",
    "@types/react-dom": "^16.9.14",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "typescript": "^3.8.3"
  },
  "devDependencies": {
    "@storybook/react": "^6.3.7",
    "babel-loader": "^8.2.2",
    "babel-preset-react-app": "^10.0.0",
    "less": "^4.1.2",
    "less-loader": "^5.0.0",
    "style-loader": "^1.3.0",
    "ts-loader": "^6.0.4"
  }
}

我们安装的依赖会根据-D参数来记录在在dependenciesdevDependencies中,如:

"dependencies": {
    "@types/react": "^16.14.14",
    "@types/react-dom": "^16.9.14",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "typescript": "^3.8.3"
  },

其中key为依赖包名,后面的value为安装的版本号。

package.json中支持以semver表示法来更新升级所需要的依赖版本。

  • ~16.13.1表示只更新补丁版本,即16.13.2可以,16.14.0不可以
  • ^16.13.1表示更新补丁版本和次版本,即16.14.0和16.13.2都可以
  • 16.13.1表示始终使用该版本

然而,在我们的项目中本地使用的版本为^16.13.1,package.json中也记录了^16.13.1。在把项目上传到github的时候,一般不会将node_modules一起上传,然而在别人拉取我们项目的时候需要npm install来安装相关的依赖,由于package.json一般不会指定具体版本,所以^16.13.1在安装的时候可能会安装成^16.13.2。所以会造成一个问题:不同开发者拉取的同一个项目,安装的依赖版本可能不相同,可能会带来一些接口的兼容问题或更新后的某些行为特征不一样。这时候我们需要package-lock.json来帮助我们指定版本,避免不必要的环境错误。

同一个依赖,在package-lock.json中是这样记录的:

"react-dom": {
      "version": "16.13.1",
      "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-16.13.1.tgz",
      "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==",
      "requires": {
        "loose-envify": "^1.1.0",
        "object-assign": "^4.1.1",
        "prop-types": "^15.6.2",
        "scheduler": "^0.19.1"
      }
    },

其中resolved保存了npm registry安装的依赖的tgz包地址,integrity是用于校验的hash值,requires记录了该依赖相应的子依赖。

有了package-lock.json,在每次npm install的时候,npm会比较两个文件,如果package.jsonpackage-lock.json中的依赖版本兼容,那会安装package-lock.json中的下载;如果不兼容,会根据package.json中的版本更新package-lock.json,再进行下载。package-lock.json的存在使得node不会自动更新package.json,必须强制指定版本安装。

为什么需要package-lock.json而不是在package.json指定一个版本?

package.json中指定模块版本,只能指定”最外层”的版本。比如将A模块固定为1.0.0版本,然而A模块依赖的B、C版本还是不受约束的^写法,如果B、C版本更新了这样也会引发类似的兼容问题。


参考:

  • https://segmentfault.com/a/1190000023729582
  • http://nodejs.cn/learn/the-package-lock-json-file
  • https://www.cnblogs.com/goloving/p/14602743.html
  • https://www.cnblogs.com/yalong/p/15013880.html
举报

相关推荐

0 条评论