OpenSCA技术原理之npm依赖解析
本文主要介绍基于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官网
由此可以构建出当前项目的依赖结构:

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。
分析到这里我们可以总结出如下图依赖关系:

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版本。
因此组件依赖结构就变成了:

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依赖解析的更多相关文章
- 解析 Android Things 技术原理
2012 年 6 月,由 IoT-GSI(Global Standards Initiative on Internet of Things)发布的白皮书“ITU-T Y.4000/Y.2060”[1 ...
- 秋色园QBlog技术原理解析:性能优化篇:缓存总有失效时,构造持续的缓存方案(十四)
转载自:http://www.cyqdata.com/qblog/article-detail-38993 文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文 ...
- <转>VPN技术原理
原文地址:VPN技术原理 VPN,Virtual Private Network(虚拟专用 网络),被定义为通过一个公用网络(通常是因特网)建立一个临时的.安全的连接,是一条穿过公用网络的安全.稳定的 ...
- Spring-Session实现Session共享实现原理以及源码解析
知其然,还要知其所以然 ! 本篇介绍Spring-Session的整个实现的原理.以及对核心的源码进行简单的介绍! 实现原理介绍 实现原理这里简单说明描述: 就是当Web服务器接收到http请求后,当 ...
- 探究Hybrid-APP技术原理
探究Hybrid-APP技术原理 author: @TiffanysBear 背景 随着Web技术的发展和移动互联网的发展,Hybrid技术已经成为一种前端开发的主流技术方案.那什么是Hybrid A ...
- Android插件化技术——原理篇
<Android插件化技术——原理篇> 转载:https://mp.weixin.qq.com/s/Uwr6Rimc7Gpnq4wMFZSAag?utm_source=androi ...
- Java 动态调试技术原理及实践
本文转载自Java 动态调试技术原理及实践 导语 断点调试是我们最常使用的调试手段,它可以获取到方法执行过程中的变量信息,并可以观察到方法的执行路径.但断点调试会在断点位置停顿,使得整个应用停止响应. ...
- 深入探索Android热修复技术原理读书笔记 —— 代码热修复技术
在前一篇文章 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍中,对热修复技术进行了介绍,下面将详细介绍其中的代码修复技术. 1 底层热替换原理 在各种 Android 热修复方案中 ...
- 深入探索Android热修复技术原理读书笔记 —— so库热修复技术
热修复系列文章: 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍 深入探索Android热修复技术原理读书笔记 -- 代码热修复技术 深入探索Android热修复技术原理读书笔记 ...
- 新手入门:史上最全Web端即时通讯技术原理详解
前言 有关IM(InstantMessaging)聊天应用(如:微信,QQ).消息推送技术(如:现今移动端APP标配的消息推送模块)等即时通讯应用场景下,大多数都是桌面应用程序或者native应用较为 ...
随机推荐
- 关于Maven执行mvn help:system命令报错
报错: [ERROR] Error executing Maven.[ERROR] 2 problems were encountered while building the effective s ...
- WPF应用开发之控件动态内容展示
在我们开发一些复杂信息的时候,由于需要动态展示一些相关信息,因此我们需要考虑一些控件内容的动态展示,可以通过动态构建控件的方式进行显示,如动态选项卡展示不同的信息,或者动态展示一个自定义控件的内容等等 ...
- 在Winform应用中增加通用的业务编码规则生成
在我们很多应用系统中,往往都需要根据实际情况生成一些编码规则,如订单号.入库单号.出库单号.退货单号等等,我们有时候根据规则自行增加一个函数来生成处理,不过我们仔细观察后,发现它们的编码规则有很大的共 ...
- [ARC165D] Substring Comparison
Problem Statement For an integer sequence $X=(X_1,X_2,\dots,X_n)$, let $X[L,R]$ denote the integer s ...
- [GDOI22pj2D] 机器人
第四题 机器人 提交文件: robot.cpp 输入文件: robot.in 输出文件: robot.out 时间空间限制: 3 秒, 512 MB 刚上初一的小纯特别喜欢机器人,这周末,她报名了学校 ...
- [CF1748D] ConstructOR
题目描述 You are given three integers $ a $ , $ b $ , and $ d $ . Your task is to find any integer $ x $ ...
- django自带的cache缓存框架使用
https://docs.djangoproject.com/zh-hans/4.2/topics/cache/#top 主要步骤官网也写得很清楚了,包含怎么区使用. 这里就展示一些配置django- ...
- 组合式api的使用方式
方式一:通过setup选项 <script> export default { setup(){ // 提供数据 // 提供函数 // 提供计算属性等等..... } } </scr ...
- MySQL 8.0.32 InnoDB ReplicaSet 配置和手动切换
1.环境准备 主库:192.168.137.4 mytest3 从库:192.168.137.5 mytest4 MySQL: 8.0.32 2.配置 ReplicaSet 实例 启动 mysql s ...
- 第三方登陆--QQ登陆--前后端分离版本
从零玩转第三方QQ登陆 下面有源码 第三方GITEE登陆 https://www.cnblogs.com/Yangbuyi/p/yangbuyi.html 在真正开始对接之前,我们先来聊一聊后台的方案 ...