npm 实现原理

2023-11-12

输入 npm install 命令并敲下回车后,会经历如下几个阶段(以 npm 5.5.1 为例):

1.执行工程自身 preinstall

当前 npm 工程如果定义了 preinstall 钩子此时会被执行。

2.确定首层依赖模块

首先需要做的是确定工程中的首层依赖,也就是 dependencies 和 devDependencies 属性中直接指定的模块(假设此时没有添加 npm install 参数)。

工程本身是整棵依赖树的根节点,每个首层依赖模块都是根节点下面的一棵子树,npm 会开启多进程从每个首层依赖模块开始逐步寻找更深层级的节点。

3.获取模块

获取模块是一个递归的过程,分为以下几步:

获取模块信息。在下载一个模块之前,首先要确定其版本,这是因为 package.json 中往往是 semantic version(semver,语义化版本)。此时如果版本描述文件(npm-shrinkwrap.json 或 package-lock.json)中有该模块信息直接拿即可,如果没有则从仓库获取。如 packaeg.json 中某个包的版本是 ^1.1.0,npm 就会去仓库中获取符合 1.x.x 形式的最新版本。
获取模块实体。上一步会获取到模块的压缩包地址(resolved 字段),npm 会用此地址检查本地缓存,缓存中有就直接拿,如果没有则从仓库下载。
查找该模块依赖,如果有依赖则回到第1步,如果没有则停止。

4.模块扁平化(dedupe)

上一步获取到的是一棵完整的依赖树,其中可能包含大量重复模块。比如 A 模块依赖于 loadsh,B 模块同样依赖于 lodash。在 npm3 以前会严格按照依赖树的结构进行安装,因此会造成模块冗余。

从 npm3 开始默认加入了一个 dedupe 的过程。它会遍历所有节点,逐个将模块放在根节点下面,也就是 node-modules 的第一层。当发现有重复模块时,则将其丢弃。

这里需要对重复模块进行一个定义,它指的是模块名相同且 semver 兼容。每个 semver 都对应一段版本允许范围,如果两个模块的版本允许范围存在交集,那么就可以得到一个兼容版本,而不必版本号完全一致,这可以使更多冗余模块在 dedupe 过程中被去掉。

比如 node-modules 下 foo 模块依赖 lodash@^1.0.0,bar 模块依赖 lodash@^1.1.0,则 ^1.1.0 为兼容版本。

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

5.安装模块

这一步将会更新工程中的 node_modules,并执行模块中的生命周期函数(按照 preinstall、install、postinstall 的顺序)。

6.执行工程自身生命周期

当前 npm 工程如果定义了钩子此时会被执行(按照 install、postinstall、prepublish、prepare 的顺序)。

最后一步是生成或更新版本描述文件,npm install 过程完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

npm 实现原理 的相关文章

  • 如何设置上传的文件名?

    By using multer I made it to request image file like this 这个文件存储在我设置的 上传 文件夹中 我的代码如下 var multer require multer var uploa
  • Firebase 模拟器启动时失败找不到模块 --dns-result-order=ipv4first

    Firebase 模拟器11 0 0无法启动 firebase emulators start 当它到达模拟器 UI 时抛出异常 i ui 模拟器 UI 日志记录到 ui debug log ui 发生致命错误 模拟器 UI 已退出 代码为
  • Angular-cli AOT 构建失败,并显示“致命错误:CALL_AND_RETRY_LAST 分配失败 - JavaScript 堆内存不足”

    我正在尝试使用 AOT 构建我的 angular cli 项目 ng build aot 但它因错误而失败 致命错误 CALL AND RETRY LAST 分配失败 JavaScript 堆内存不足 如果我用 prod flag 任何想法
  • Node.js 和 Passport 对象没有 validPassword 方法

    我正在使用 Node js Express Passport 创建一个简单的身份验证 本地 到目前为止我所达到的效果是 当输入错误的用户名或密码时 用户将被重定向到错误页面 但是当用户输入正确的用户名和密码时 我收到此错误 node mod
  • 在heroku上部署时出错,/bin/sh: 1: webpack: not found

    这是我在 heroku 网站上手动部署时遇到的错误 首先 我在 json 文件中遇到错误 因此我指定了正在运行的 npm yarn 和 node 版本 这些错误似乎已经清除 现在我就是这样的人 并且已经搜索了谷歌 但似乎找不到太多关于修复它
  • 如何更改服务器端口3000?

    我刚刚结束了 Angular 2 的教程 我找不到将 localhost 端口从 3000 更改为 8000 的方法 在我的package json文件中有一行 start concurrent npm run tsc w npm run
  • Node js 使用中间件重定向进行过多重定向

    在我的 Node js 应用程序 我使用的是express 4 x 中 我想检查用户是否已登录 如果用户未登录 我想重定向到我的登录页面 然后我在中间件中这样做 服务器 js app use function req res next if
  • 具有 Firebase (FCM) 推送通知的 Node js

    我正在使用 Node js 开发 REST api 并且有一个休息端点来发送 firebase 推送通知 我的代码如下 const bodyParser require body parser var cors require cors v
  • 通过 node-http-proxy 保留基于 cookie 的会话

    我有一个简单的基于 Express 的 Node js Web 服务器 用于开发 JavaScript 应用程序 我将服务器设置为使用 node http proxy 来代理应用程序向在不同域和端口上运行的 Jetty 服务器发出的 API
  • 如何在node.js中的一定时间后强制解决承诺? [复制]

    这个问题在这里已经有答案了 我正在尝试从其 url 下载大量图像 然后在 Node js 中创建一个 PDF 文件 我正在使用图片下载器 https www npmjs com package image downloader模块下载承诺链
  • 猫鼬不创建索引

    我最近开始使用 Mongoose v 3 2 1 但我遇到了索引问题 我在我的模式 Schema path attr index true 上定义了几个索引 但它们不是在数据库中创建的 我在 shell 中运行 db collection
  • 为什么我们不能在 Express.js 中执行多个response.send?

    3年前我可以做多个res send在express js中 甚至写一个setTimeout显示实时输出 response send response send
  • node.js 安装向导提前结束

    我无法安装 node js 0 8 9 我是通过安装向导完成的 每次安装结束时我都会收到消息 Node js 安装向导提前结束 会是什么呢 谢谢 这可能会对将来的某人有所帮助 我从安装程序中收到类似的消息 发现我可以转到命令提示符并使用命令
  • 使用 Node.js mongodb 本机调用 db.destroyDatabase 时,什么可能导致“拓扑被破坏”错误?

    我正在使用 Node js Mongodb 本机驱动程序运行一些集成测试 每个测试都涉及连接到数据库 验证它是否尚不存在 例如 没有任何带有文档的集合 运行测试 然后删除数据库 高级代码如下 const runSafeTest functi
  • Node + Express 会话过期?

    我有一个 Express 应用程序 并且有一个登录表单 我需要持续 1 个月的会话 我是否将 maxAge 设置为一个月 以毫秒为单位 我让两台计算机保持打开状态并登录了 24 小时 当我回来时 两台计算机都已注销 我该如何解决这个问题 实
  • Node.js 每个用户一个会话

    如何防止我的用户同时从两个设备登录我的系统 因此 如果用户从计算机登录 当他从不同的计算机登录时 首先会自动关闭会话 不需要使其实时 我使用node js express js mongoose passport connect mongo
  • 如何将中间件绑定到socket.io中的事件

    现在您可以将中间件绑定到io use middleware 但这仅在建立套接字连接时触发 有没有办法在将其传递给事件句柄之前拦截它 就像在expressjs中一样 换句话说 In 快递 js你可以做 app get middleware1
  • 由于预发布,Node 应用程序无法运行

    即使安装成功 我也会安装无效的软件包 顺便说一句 这个问题与答案相关 关于版本控制的问题 https stackoverflow com questions 27628153 npm versioning how does this edg
  • 何时不使用承诺[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在阅读了数十篇关于 es6 Promise 有多伟大以及为什么我们应该实现它们的文章之后 我有这样的感觉 ALL我的 不平凡的 JavaScri
  • 如何以非阻塞方式在 Node.js 中搜索数组?

    我有一个数组是 4ff023908ed2842c1265d9e4 4ff0d75c8ed2842c1266099b 我必须找出以下内容是否在该数组内 4ff0d75c8ed2842c1266099b 这是我写的 Array prototyp

随机推荐

  • Qt实现点击按钮弹出(关闭)窗口,点击窗口外其他位置关闭窗口

    Qt实现点击按钮弹出 关闭 窗口 点击窗口外其他位置关闭窗口 方法一 在窗口实现类的构造函数中添加如下代码 this gt setWindowFlags Qt Popup 参数Qt Popup 表示 当点击窗口以外就关闭窗口 方法二 直接在
  • python 图片、文件 通过 request header 多线程下载

    写爬虫过程中发现图片下载比较慢 遂使用多线程下载来提速 import threading import requests class MulThreadDownload threading Thread def init self url
  • select回显注意问题

    span style font size 18px js代码 span span style font size 18px var roleName entity roleId 5 roleId val roleName span span
  • 网络安全应急响应预案培训

    应急响应预案的培训是为了更好地应对网络突发状况 实施演 练计划所做的每一项工作 其培训过程主要针对应急预案涉及的相 关内容进行培训学习 做好应急预案的培训工作能使各级人员明确 自身职责 是做好应急响应工作的基础与前提 应急响应预案的培 训分
  • 2024年java面试--mysql(3)

    系列文章目录 2024年java面试 一 spring篇 2024年java面试 二 spring篇 2024年java面试 三 spring篇 2024年java面试 四 spring篇 2024年java面试 集合篇 2024年java
  • Photoshop 之利用 "调整边缘" 抠图

    目录 1 首先 看如下图像 人物图像包含很多头发 2 利用魔棒工具 选中选区 并选择 反向 选中人物图像 3 选择选项栏中的 调整边缘 或者菜单栏中的选择 调整边缘 4 利用调整边缘 修复毛发中的空白部分扣除 5 通过拷贝的图层 将图像抠出
  • 如何安装和使用Android夜神模拟器

    夜神模拟器 是全新一代的安卓模拟器 能够让你在电脑上畅玩手机游戏 与传统安卓模拟器相比 基于Android7 1内核 同时向下兼容Android5 1内核以及X86 AMD 具备极高的兼容性和稳定性 加上超高帧率模式 能够在电脑上运行高性能
  • Antd的Upload+fetch+FormData上传Excel文件请求方式?

    let formData new FormData formData append file fileList 0 fetch 接口名称 method POST headers Content Type multipart form dat
  • 平均年薪60.8万,程序员拿下这个证书有多吃香?!

    互联网行业竞争一年比一年严峻 随着互联网的发展和进步 很多人都是想要进军到编程行业中去 作为工程师的我们唯有不停地学习 不断的提升自己才能保证自己的核心竞争力 打破内卷 从而拿到更好的薪水 进入心仪的企业 前些天 我的程序员哥们和我说 他转
  • Pycharm关闭项目卡住怎么办?

    突然有一天创建新项目的时候 Pycharm卡在了关闭项目上 通过网上查阅资料 不断试探 我最终这样解决了 1 在设置中的自然语言中添加了中文 2 更新了Pycharm由2023 1到2023 4 3 在文件中关闭项目 然后等待了较长时间后
  • Sentinel分布式系统的流量防卫兵

    Sentinel 是什么 官网 https github com alibaba Sentinel wiki 介绍 随着微服务的流行 服务和服务之间的稳定性变得越来越重要 Sentinel 以流量为切入点 从流量控制 熔断降级 系统负载保护
  • ae2020不支持的视频驱动程序_AE 2020版本安装提示系统兼容性报告怎么解决?

    AE 2020版本安装提示系统兼容性报告怎么解决 很多设计师朋友会遇到这样的问题 安装完AE2020版本之后 打开软件 提示这样的信息显示系统兼容性报告可这样解决 快进来学习吧 系统是WIN10的 64位 点击不理会 可以打开软件 但是作为
  • ​LeetCode刷题实战26:删除排序数组中的重复项

    算法的重要性 我就不多说了吧 想去大厂 就必须要经过基础知识和业务逻辑面试 算法面试 所以 为了提高大家的算法能力 这个公众号后续每天带大家做一道算法题 题目就从LeetCode上面选 今天和大家聊的问题叫做 删除排序数组中的重复项 我们先
  • vite 配置自动补全文件的后缀名

    vite 不建议自动补全 文件的后缀名的 const Home gt import views Home vue 文件是必须要加上 vue 的后缀名的 如果 想要像 webpack 一样的不用写 可以在vite config js中配置如下
  • windows server 2012 R2 安装mysql(一)

    windows server 2012 R2 安装mysql 一 最近遇到一个要做app的朋友 朋友想要做一个简单的线上APP app 的功能久不介绍了 笔者决定采用windows server 2012 r2 做应用服务器 数据库采用my
  • 疫情防控数据可视化平台的设计与实现 计算机专业毕业设计源码87063

    摘要 信息化社会内需要与之针对性的信息获取途径 但是途径的扩展基本上为人们所努力的方向 由于站在的角度存在偏差 人们经常能够获得不同类型信息 这也是技术最为难以攻克的课题 针对疫情防控数据可视化平台等问题 对如何通过计算机疫情防控数据可视化
  • 在Qt创建的UI中放一个显示点云的窗口(PCL+QT5)

    1 首先在Qt Designer创建UI后 拖一个Widget窗口出来 2 在对象查看器中右击该Widget 选择提升窗口部件 如下操作 3 把UI转出来放在VS项目中 其中你的UI代码头文件会自带QVTKOpenGLNativeWidge
  • 非常实用: 2.4G天线设计指南(赛普拉斯工程师力作)

    前言 为了方便查看博客 特意申请了一个公众号 附上二维码 有兴趣的朋友可以关注 和我一起讨论学习 一起享受技术 一起成长 转载自 gt 非常实用 2 4G天线设计指南 赛普拉斯工程师力作 微信公众号 lt lt 射频百花潭 gt gt 本文
  • 分享 7 个 AI 优质开源项目!文本生成、自动化数据搜集...

    项目一 nanodet 超快速轻量级无锚物体检测模型 项目地址 https github com RangiLyu nanodet 项目特点 超轻量 模型文件只有 980KB INT8 或 1 8MB FP16 超快 在移动 ARM CPU
  • npm 实现原理

    输入 npm install 命令并敲下回车后 会经历如下几个阶段 以 npm 5 5 1 为例 1 执行工程自身 preinstall 当前 npm 工程如果定义了 preinstall 钩子此时会被执行 2 确定首层依赖模块 首先需要做