最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • npm install模块安装机制

    正文概述 掘金(杨Young)   2021-08-25   392

    为什么执行npm install会更新package-lock.json?

    你是否也有疑惑,为什么介入新项目初始化的时候,执行npm install安装依赖,项目的package-lock.json有时候会更新?package-lock.json就是用来固定依赖版本的,按理说依赖的版本都固定了,又没有安装新的依赖就不应该改变的,这是为什么?如果你也有这样的疑问,那么接下来可以进一步跟随我去了解npm install的模块安装机制。当然需要明确一下,这里提到的npm版本version 5及其之后的版本,因为在此之前,还未有package-lock.json之类的配置文件。

    npm install(不带参数)安装机制

    npm install模块安装机制

    确定首层依赖

    先检查package.json,通过dependencies和devDependencies属性中直接指定的模块。

    构建依赖树

    确定首层依赖后,会去构建依赖树。这是一个递归的过程,工程本身是整棵依赖树的根节点,每个首层依赖模块都是根节点下面的一棵子树,npm 会开启多进程从每个首层依赖模块开始逐步寻找更深层级的节点,形成依赖树。每个节点在递归的过程中会去确定节点模块的信息,比如版本、下载地址、压缩包地址等。

    版本的确定机制:

    package.json 中往往是 semantic version(semver,语义化版本)。此时如果版本描述文件(npm-shrinkwrap.json 或 package-lock.json)中有该模块信息直接拿即可,如果没有则从远程仓库获取。如 packaeg.json 中某个包的版本是 ^1.0.0,npm 就会去仓库中获取符合 1.x.x 形式的最新版本。

    依赖树扁平化

    上一步得到的依赖树,一般是包含很多重复模块的,比如A模块依赖了moment,B模块也依赖了moment,npm在npm3之后进行了优化,不在严格按照依赖树来进行安装,因为这个过程会浪费大量资源和时间。做法就是对这颗树进行扁平化处理。即简单说来,它会遍历所有节点,逐个将模块放在根节点下面,也就是 node_modules 的第一层。当发现有重复模块时,则将其丢弃。

    比如 node_modules 下 A 模块依赖 moment@^1.0.0,B 模块依赖 moment@^1.1.0,则 ^1.1.0 为兼容版本。

    而当 A 模块依赖 moment@^2.0.0,B 模块依赖 moment@^1.1.0,则依据 semver 的规则,二者不存在兼容版本。会将一个版本放在 node_modules 中,另一个仍保留在依赖树里。

    举个例子,假设一个依赖树原本是这样:

    node_modules

    -- moduleA

    ---- moment@version1

    -- moduleB

    ---- moment@version2

    假设 version1 和 version2 是兼容版本,则经过 扁平化 会成为下面的形式:

    node_modules

    -- moduleA

    -- moduleB

    -- moment(保留的版本为兼容版本)

    假设 version1 和 version2 为非兼容版本,则后面的版本保留在依赖树中:

    node_modules

    -- moduleA

    -- moment@version1

    -- moduleB

    ---- moment@version2

    获取依赖树确定的模块

    先会通过压缩包地址去判断是否在缓存中存在该版本模块,如果有,就直接拿过来,如果没有,就回去远程仓库下载,下载完后放入缓存,并解压放到node_modules目录中,最后会去新增或者更新lock文件。

    回答文章刚开始提出的问题

    其实基本看完上面的内容,应该能够回答开篇的题目了。这里我再明确的表述一下。

    先明确一个机制:

    ## package.json
    "dependencies": {  
      "core-js": "~3.4.5"  
    }
    ## package-lock.json
    "dependencies": {  
      "core-js": {  
        "version": "3.4.7",  
        "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.4.7.tgz",  
        "integrity": "sha1-PdplYR2VaZtet3QupFHqBS03qmU="  
      }  
    }
    

    如上示例代码,依赖的是core-js ~3.4.5, 锁定的是3.4.7。 你把package.json里 core-js 的依赖改成 ~3.4.6 , ~3.4.7,重新安装都不会使 package-lock.json变化, 因为lock文件里面保存的版本比package文件里面的大。但是如果你把package.json文件里面的版本直接改成 "core-js": "~3.4.8", 这就比lock文件里面的版本要高了,需要重新下载最新的,会下载符合3.5.x 的最新版。同时更新lock文件。

    明确这个机制后,再结合上面构建依赖树的过程,npm install并不是完全按照lock文件去安装依赖的,是先通过package.json创建依赖,再去看lock(这个lock我认为是模块的lock,需要指明的是,很多npm模块没有lock类文件)中对应的模块固定的版本是否符合semver规则,符合就直接安装,不符合就会按照package.json的指定的semver规则去仓库拉最新的版本信息并更新lock文件(这个lock是工程的lock)。

    npm ci

    之所以提这个命令,是因为开篇的那个问题,其实有一层含义就是提问者想要通过lock固定下来的版本安装工程,不想有任何版本变化,保持绝对一致。那么npm ci就是为此而生的。这个命令会完全按照工程的lock描述文件去安装依赖。要注意的是,当lock文件的描述版本不满足package.json依赖指定到semver规则时,会报错退出,并不会往下执行或者去更新lock文件。


    起源地下载网 » npm install模块安装机制

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元