[toc] >[success] # package-lock.json ~~~ 1.在npm5 中,npm 引入了'package-lock.json'文件,为什么已经有了'package.json'还要 引入'package-lock.json'? 1.1. 'package.json'可以使用 semver 表示法设置要升级到的版本(补丁版本或次版本), (补充说明:'semver' 是一种版本规规范,想了解更多看上一个章节),举个例子 "devDependencies": { "fibers": ">= 3.1.1 <5.0.0", "sass": "^1.26.5", "sass-loader": "^8.0.2", "vue": "^2.6.11", "vue-router": "^3.2.0", "vue-template-compiler": "^2.6.11", "vuex": "^3.4.0" } 举个例子在开发初期使用我们使用的vue版本声明定义'vue: ^2.5.1',某个阶段有新的 开发加入我们团队,并且此时vue版本最新版本已经到了'2.6.1',那么当他执行'npm install' 时候根据 'semver'版本规则安装版本将会是vue ^2.5.1 = >=2.5.1 <3.0.0, npm会选择安装 2.6.1,因为它在匹配版本范围内,且是目前最新的vue2的版本,它不会选择2.5.0和3.0.0 这时候使用了新提供一些方法或者api 很有可能当你拉下代码时候出现一些报错,除非你 重新更新你本地'node_modules' 1.2.'package.json问题':在package.json中通常做了锁定大版本的操作,这样在每次npm install的时候都会拉取依赖包大版本下的最新的版本。这种机制最大的一个缺点就是当有 依赖包有小版本更新时,可能会出现协同开发者的依赖包不一致的问题。 ~~~ >[info] ## package-lock.json 来解决问题 ~~~ 1.如何解决这类问题出现,最简单的方法将'node_modules'提交大家保持统一,但是 该文件夹通常很大,那我们将所有包固定指定确切的版本,问题是体验不到更新的快乐 2.那提出一个方案,这个方案可以具备我们上面第一条形式但又避免第一条形式出现 的问题,我们采用一个 'json' 文件,他可以记录我们'node_modules' 文件目录结构 和此时此刻你安装包的具体版本,这样我们在配合一个更新指令在想要更新的时候 可以将包版本更新,这样就不用提交庞大的'node_modules' 和将每个包版本锁住 还要注意固定版本只是固定来自身的版本,依赖的版本无法固定 'package-lock 出现': 3.'package-lock.json'文件精确描述了'node_modules' 目录下所有的包的树状依赖结构,每个包的版本号都是完全精确的,这样'package-lock.json '文件需要被提交到 Git 仓库, 'package-lock.json'可以理解成是一个'node_modules' 这样现在大家的'node_modules' 都是一个版本,如果想更新新的版本包当运行 npm update 时,package-lock.json 文件 中的依赖的版本会被更新 ~~~ >[info] ## package-lock.json 文件的作用 ~~~ 1.在团队开发中,确保每个团队成员安装的依赖版本是一致的,确定一棵唯一的 'node_modules'树 2.'node_modules' 目录本身是不会被提交到代码库的,但是 'package-lock.json' 可以提交 到代码库,如果开发人员想要回溯到某一天的目录状态,只需要把 'package.json' 和 'package-lock.json' 这两个文件回退到那一天即可。 3.由于 'package-lock.json' 和 'node_modules' 中的依赖嵌套完全一致,可以更加清楚的 了解树的结构及其变化。 4.在安装时,npm 会比较 'node_modules' 已有的包,和' package-lock.json' 进行比较, 如果重复的话,就跳过安装 ,从而优化了安装的过程。 ~~~ >[info] ## package-lock.json 结构 1. 构成字段**version、resolved、integrity、dev、requires、dependencies、name、lockfileVersion** 1.1. '**version**':包唯一的版本号 1.2. '**resolved**':安装源 1.3. '**integrity**':表明包完整性的hash值(验证包是否已失效),用来从缓存中获取索引,再通过索引去获取压缩包文件 1.4. '**dev**':如果为true,安装时候是开发依赖 1.5. '**requires**':依赖包所需要的所有依赖项,对应依赖包package.json里dependencies中的依赖项 1.6. '**dependencies**':依赖包node_modules中依赖的包,与顶层的dependencies一样的结构有些依赖包中还会有一层'node_modules' 1.7. **lockfileVersion**:lock文件的版本; 1.8. **name**:项目的名称; 2. 下图安装了一个'sass-loader'**,可以看到'package-lock.json 结构' 和'node_modules' 文件结构是一样的**,这样'package-lock.json文件提交到代码版本仓库'**后拉取安装后 安装的依赖版本都是一致的** ![](https://img.kancloud.cn/35/50/35503702a1fad9e6093876c4f48de5d4_1439x609.png) 3. 但是在**开发一个库时**,则**不应把package-lock.json文件发布到仓库中**。实际上,**npm也默认不会把package-lock.json文件发布出去**。之所以这么做,是因为**库项目一般是被其他项目依赖的,在不写死的情况下,就可以复用主项目已经加载过的包,而一旦库依赖的是精确的版本号那么可能会造成包的冗余。** >[info] ## 文件参考 [package-lock.json 文件的作用](https://www.infoq.cn/article/qj3z2ygrzdgicqauaffn)