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应用较为 ...
随机推荐
- java中的try-with-resource语法
java的世界千奇百怪...当我甩出如下代码段,不知阁下如何应对? try(A a=new A()){ 和a变量无关的业务代码块 } 没错,这就是"臭名昭著"的try-with-r ...
- 深入解析LLaMA如何改进Transformer的底层结构
本文分享自华为云社区<大语言模型底层架构你了解多少?LLM大底层架构之LLM模型结构介绍>,作者: 码上开花_Lancer . 大语言模型结构当前绝大多数大语言模型结构都采用了类似GPT ...
- 基于python人脸识别考勤系统(语音播报)
介绍: 本项目是大二寒假在家没事写的,一直没有时间讲本项目分享出来,现在有时间了哈.那就让我简单的将项目介绍一下吧.好了废话不多说了,直接上图 初始化界面: 可以看到所有的功能都展现在了左边的功能栏中 ...
- LeetCode132:分割回文串(DP、回文)
解题思路:有两个问点:1.如何快速当前字符串哪些的字串是回文:2.如何组合这些字串达到分割次数最少 针对问点1,可以开辟一个二维布尔数组 a[][],a[i][j]表示以索引i为起点,j为结束位置的字 ...
- HP LoadRunner 11.00安装+破解+汉化
里面包含多个破解码,最高支持6.5w个并发: https://blog.csdn.net/xianjie0318/article/details/78625980
- linux云服务器病毒处理
阿里云服务器被挖矿病毒入侵,CPU跑满,需要先停止相关进程.为了根除病毒,还需要 解决系统的后门问题(这部分听从阿里云工程师的建议备份系统盘快照后重置系统,再通过快照恢复数据) 然而重置系统后依然存在 ...
- Langchain-Chatchat项目:1.2-Baichuan2项目整体介绍
由百川智能推出的新一代开源大语言模型,采用2.6万亿Tokens的高质量语料训练,在多个权威的中文.英文和多语言的通用.领域benchmark上取得同尺寸最佳的效果,发布包含有7B.13B的Bas ...
- .NET Conf China 2023分享-.NET应用国际化-AIGC智能翻译+代码生成
今年.NET Conf China 2023技术大会,我给大家分享了 .NET应用国际化-AIGC智能翻译+代码生成的议题,今天整理成博客,分享给所有人. 随着疫情的消退,越来越多的企业开始向海外拓展 ...
- 浏览器工作原理和实践(二)——JavaScript
<浏览器工作原理与实践>是极客时间上的一个浏览器学习系列,在学习之后特在此做记录和总结. 一.执行流程 实际上变量和函数声明在代码里的位置是不会改变的,而且是在编译阶段被 JavaScri ...
- MySQL进阶篇:详解索引分类和索引语法
MySQL进阶篇:第二章_二.三_ 索引分类和索引语法 索引分类 在MySQL数据库,将索引的具体类型主要分为以下几类:主键索引.唯一索引.常规索引.全文索引. 分类 含义 特点 关键字 主键索引 针 ...