package-lock.json说明

4,241 阅读2分钟

package-lock.json文件作用

背景

  1. npm使用semver版本控制,方便开发者使用特定的版本跟踪策略,比如:自动更新一些版本(bug修复等)
  2. 但是npm semver版本控制策略可能导致一些问题:
    1. 团队内不同的队友(teammates)可能实际上依赖的版本并不一致
    2. 本地开发环境或者其他环境阶段安装的依赖不一致
    3. 这些运行时环境不一致的问题,最终可能导致本地或者测试环境能够正常运行的代码,在生产环境中却产生了异常。

为了达到不同成员、不同环境的依赖保持一致的效果,采用了package-lock.json来锁定特定的版本。

官方给出了几个目的:

  1. 在不同的团队成员或者发布、持续集成过程中保持唯一的依赖关系树,都安装完全相同的依赖。
  2. 提供了一种便利的方案,能够随时回退代码到某个历史版本,这个版本包含了特定的版本依赖,而不用node_modules也提交到代码仓库中。
  3. 方便对依赖更改做代码diff。
  4. 优化安装依赖过程,跳过那些已经安装的依赖
  5. 性能提升(没搞懂!)

package-lock.json组成

{
  "name": "assets-system",//和package.json中name保持一致
  "version": "0.1.0", // 和package.json中name保持一致
  "lockfileVersion": 1,
  "requires": true,
  "dependencies":[] //当前包的依赖锁定依赖树
}

部分字段说明

resolved

依赖包的下载地址,对应使用npm registry安装的依赖,都是指向一个tarball地址。

integrity

"source-map": {
  "version": "0.5.7",
  "resolved": "http://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz",
  "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
}

integrity是用来验证资源的完整性,即是否是我期望加载的资源,而不是被别人篡改了内容。

  1. package-lock.json中使用了W3C的标准w3c webappsec-subresource-integrity
  2. integrity由两部分组成: 加密hash函数-摘要dgest,其中:dgest=base64(hashfn(content))
  3. npm中使用的加密hash函数有两种:sha512或者sha1

验证资源完整性过程

  1. 获取integrity字段,得到加密hash算法fn和摘要dgest
  2. 使用fn对获取到的资源内容进行加密,然后对加密后的结果使用base64编码,得到摘要dgest2
  3. 如果dgest===dgest2,证明资源没有被篡改。

举例:验证下面包的资源完整性

"source-map": {
  "version": "0.5.7",
  // 包的下载地址
  "resolved": "http://registry.npm.taobao.org/source-map/download/source-map-0.5.7.tgz",
  // integrity字段
  "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
}
  1. 下载包内容registry.npm.taobao.org/source-map/…
  2. 使用sha1加密函数和base生成摘要
    shasum -b -a 384 ./source-map-0.5.7.tgz | xxd -r -p | base64
    igOdLRAh0i0eoUyA2OpGi6LvP8w=
    
  3. 发现结果和我们的integrity字段中包含的字段一致
  4. 同时你可以下载npmjs源的包,进行2-3步骤的验证,同样资源完整。

即使你只是解压,重新打包,也同样导致校验失败。

参考

  1. w3c webappsec-subresource-integrity
  2. MDN Subresource_Integrity