本文主要介绍基于npm包管理器的组件成分解析原理。

npm 介绍

npm(全称Node Package Manager)是Node.js的预设软件包管理器。

npm的依赖管理文件是package.json。开发者可以在package.json中指定每个依赖项的版本范围。如果一个项目中存在package.json文件,便可以执行npm install命令自动安装和维护当前项目所需的所有模块并生成package-lock.json文件。

package.json完整文件结构如下:

{
"name": "screeps",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"push": "rollup -cw --environment DEST:main",
"build": "rollup -cw --environment DEST:local",
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-node-resolve": "^13.1.1",
"@types/lodash": "^3.10.1",
"@types/screeps": "^3.2.4",
"rollup": "^2.61.1",
"rollup-plugin-clear": "^2.0.7",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-screeps": "^1.0.1",
"rollup-plugin-typescript2": "^0.31.1",
"typescript": "^4.5.4"
},
"dependencies": {
"source-map": "^0.6.1"
}
}

其中name为项目名,version为项目版本,license为项目声明的许可证。

devDependencies为开发环境使用的依赖,dependencies为生产环境使用的依赖。

依赖写法为"name":"version",版本可以指定准确版本或一个范围,范围需遵循semver语义化版本规范

解析算法

package-lock.json

package-lock.json文件为自动生成的文件,可以准确定位到npm项目使用的依赖及版本,所以优先解析package-lock.json文件。

package-lock.json文件结构如下:

{
"name": "foo",
"version": "1.0.0",
"dependencies": {
"b": {
"version": "1.2.1"
},
"a": {
"version": "2.1.5",
"requires": {
"b": "^1.1.9"
}
},
"c": {
"version": "1.3.1",
"requires": {
"b": "^1.2.0"
}
}
}
}

其中name字段为项目名称,version字段为项目版本。

dependencies字段中包含项目使用的所有直接和间接依赖,而且记录了组件间的依赖关系。

例如:

"b": {
"version": "1.2.1"
},

代表组件b的版本号为1.2.1

"a": {
"version": "2.1.5",
"requires": {
"b": "^1.1.9"
}
},

代表项目依赖2.1.5版本的组件a,且该组件依赖版本约束为^1.1.9的组件b

同理可知项目依赖1.3.1版本的组件c,且该组件依赖版本约束为^1.2.0的组件b

且组件a和组件c都没有被其他依赖所依赖,所以可知这两个组件是项目的直接依赖

仅通过package-lock.json无法确定组件b是否是直接依赖,可以结合package.json文件进一步确定,没有package.json时,将b当作间接依赖处理。

若一个组件同时为直接和间接依赖,按直接依赖处理。

^1.1.9代表版本号需要>=1.1.9<2.0.0

^1.2.0代表版本号需要>=1.2.0<2.0.0

更多约束格式请参阅semver官网

由此可以构建出当前项目的依赖结构:

graph
root[foo:1.0.0]
a[a:2.1.5]
b[b:1.2.1]
c[c:1.3.1]
root-->a-.->b
root-->c-.->b

实线代表直接依赖,虚线代表间接依赖

package.json

package.json为开发者编写管理的依赖管理文件,在未找到package-lock.json文件时将解析该文件。

package.json仅包含直接依赖,在项目构建时会从npm仓库下载需要的间接依赖并构建为package-lock.json文件,因此可以模拟npm构建流程来获取项目引用的组件依赖。

package.json文件结构如下:

{
"name": "foo",
"version": "1.0.0",
"devDependencies": {
"a": "^2.0.0"
},
"dependencies": {
"c": "^1.1.0"
}
}

dependencies为项目实际使用的直接依赖,devDependencies为项目开发时使用的直接依赖。

例如:

"devDependencies": {
"a": "^2.0.0"
}

代表项目开发过程中依赖版本约束为^2.0.0的组件a

"dependencies": {
"c": "^1.1.0"
}

代表项目直接依赖版本约束为^1.1.0组件c

分析到这里我们可以总结出如下图依赖关系:

graph
root[foo:1.0.0]
a[a:^2.0.0]
c[c:^1.1.0]
root-->a
root-->c

通过该依赖关系可以看出项目组件的直接依赖及组件的版本范围,但无法得知组件依赖的具体版本。

在没有package-lock.json文件的情况下,为了进一步获取依赖的准确版本及间接依赖,需要从npm仓库下载对应组件的详细信息。

例如组件a的详细信息结构为:

{
"time": {
"2.1.5": "2011-02-16T22:31:02.088Z",
"3.1.1": "2011-04-10T12:23:22.088Z"
},
"versions": {
"2.1.5": {
"dependencies": {
"b": "^1.1.9"
}
},
"3.1.1": {
"dependencies": {
"b": "^2.2.0"
}
}
}
}

其中time字段为组件所有版本及发布日期,根据约束从这里获取约束范围内的最大版本。

versions字段为组件各个版本对应的详细信息,其中dependencies字段为组件的依赖信息。

对于本例来说,组件a的约束为^2.0.0,要求版本号>=2.0.0<3.0.0,所以选择2.1.5版本。

因此组件依赖结构就变成了:

graph
root[foo:1.0.0]
a[a:2.1.5]
c[c:^1.1.0]
b[b:^1.1.9]
root-->a-.->b
root-->c

按照这种方式层级解析便可获取整个项目的依赖信息。

OpenSCA技术原理之npm依赖解析的更多相关文章

  1. 解析 Android Things 技术原理

    2012 年 6 月,由 IoT-GSI(Global Standards Initiative on Internet of Things)发布的白皮书“ITU-T Y.4000/Y.2060”[1 ...

  2. 秋色园QBlog技术原理解析:性能优化篇:缓存总有失效时,构造持续的缓存方案(十四)

    转载自:http://www.cyqdata.com/qblog/article-detail-38993 文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文 ...

  3. <转>VPN技术原理

    原文地址:VPN技术原理 VPN,Virtual Private Network(虚拟专用 网络),被定义为通过一个公用网络(通常是因特网)建立一个临时的.安全的连接,是一条穿过公用网络的安全.稳定的 ...

  4. Spring-Session实现Session共享实现原理以及源码解析

    知其然,还要知其所以然 ! 本篇介绍Spring-Session的整个实现的原理.以及对核心的源码进行简单的介绍! 实现原理介绍 实现原理这里简单说明描述: 就是当Web服务器接收到http请求后,当 ...

  5. 探究Hybrid-APP技术原理

    探究Hybrid-APP技术原理 author: @TiffanysBear 背景 随着Web技术的发展和移动互联网的发展,Hybrid技术已经成为一种前端开发的主流技术方案.那什么是Hybrid A ...

  6. Android插件化技术——原理篇

    <Android插件化技术——原理篇>     转载:https://mp.weixin.qq.com/s/Uwr6Rimc7Gpnq4wMFZSAag?utm_source=androi ...

  7. Java 动态调试技术原理及实践

    本文转载自Java 动态调试技术原理及实践 导语 断点调试是我们最常使用的调试手段,它可以获取到方法执行过程中的变量信息,并可以观察到方法的执行路径.但断点调试会在断点位置停顿,使得整个应用停止响应. ...

  8. 深入探索Android热修复技术原理读书笔记 —— 代码热修复技术

    在前一篇文章 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍中,对热修复技术进行了介绍,下面将详细介绍其中的代码修复技术. 1 底层热替换原理 在各种 Android 热修复方案中 ...

  9. 深入探索Android热修复技术原理读书笔记 —— so库热修复技术

    热修复系列文章: 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍 深入探索Android热修复技术原理读书笔记 -- 代码热修复技术 深入探索Android热修复技术原理读书笔记 ...

  10. 新手入门:史上最全Web端即时通讯技术原理详解

    前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...

随机推荐

  1. 解决IDEA加载maven工程缓慢

    如图,哪里没有加哪里 -DarchetypeCatalog=internal

  2. Opencv实例练习

    实例所用的函数可在另一篇文章查询:  https://www.cnblogs.com/Zhouce/p/17867164.html 1.图像读取 1 import cv2 # 引入opencv库 2 ...

  3. 深入浅出 PLT/GOT Hook与原理实践

    动态链接 计算机程序链接时分两种形式:静态链接和动态链接. 静态链接在链接时将所有目标文件中的代码.数据等Section都组装到可执行文件当中,并将代码中使用到的外部符号(函数.变量)都进行了重定位. ...

  4. 企业数据分析免费试用的BI工具,有什么推荐?

    当涉及到企业数据分析的免费试用BI工具时,有几个受欢迎且功能强大的选项可供选择.以下是对每个工具的详细介绍,帮助您了解其特点和优势. Datainside BI(https://datainside. ...

  5. VScode 中利用virtualenv建立 Python 虚拟环境

    ! https://zhuanlan.zhihu.com/p/638114885 VScode 建立 Python 虚拟环境 主要目的:创建一个与默认 python 版本不同的 python 虚拟环境 ...

  6. [gym104076][CCPC2022济南站L] Tree Distance

    You are given an unrooted weighted tree \(T\) with vertices \(1,2,-,n\). Please answer some queries. ...

  7. [ABC261D] Flipping and Bonus

    Problem Statement Takahashi will toss a coin $N$ times. He also has a counter, which initially shows ...

  8. IoC入门案例

    1.管理什么?(Service和Dao) 2.如何将被管理的对象告知IoC容器?(配置) 3.被管理的对象交给IoC容器,如何获取IoC容器?(接口) 4.IoC容器得到后,如何从容器中获取到bean ...

  9. SpringBoot事件机制

    1.是什么? SpringBoot事件机制是指SpringBoot中的开发人员可以通过编写自定义事件来对应用程序进行事件处理.我们可以创建自己的事件类,并在应用程序中注册这些事件,当事件被触发时,可以 ...

  10. 流畅的orm让我发现我抵触的是mybatis而不是java

    流畅的orm让我发现我抵触的是mybatis而不是java 背景介绍 开发.net 也快10年了,到第三年的时候我已经渐渐瓶颈了,于是我在网上找各种资料但是大部分c#资料全是皮毛资料,稍微深一点点就再 ...