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应用较为 ...
随机推荐
- CSS(不定时更新)
一.使用img后的高度多了4px 由于img是行内元素,默认display: inline; 它与文本的默认行为类似,下边缘是与基线(baseline)对齐,而不是紧贴容器下边缘. 将displayp ...
- HDU 4787 GRE Revenge
Now Coach Pang is preparing for the Graduate Record Examinations as George did in 2011. At each day, ...
- Python+Selenium+Webdriver+unittest 实现登录126邮箱
第一版:登录 #encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webd ...
- python生成列表的时间复杂度
在刷题的时候,经常碰到需要生成非常大的邻接矩阵,往往我们都是用 list 存储,但是我在最近刷题的过程中就遇上了TLE的情况,原因就是生成邻接矩阵时间太花时间了. 先说结论:[ ]* n 比 [ fo ...
- bash shell笔记整理——less命令
less命令的作用 less和cat.more最大的差别在于不会一次性加载整个文件,速度比较快!另外less具备翻页功能,可以向上/向下翻页! 语法 less [选项] [文件名] *选项* *使用说 ...
- NetSuite 开发日记:SDF 基础指南
VS Code 使用 SDF SuiteCloud : Create Project SuiteCloud : Set Up Account (连接沙盒环境) SuiteCloud : Import ...
- apache+mysql+php环境安装及配置
一.安装mysql 1.yum安装mysql # yum -y install mysql mysql-server 2.安装mariadb,用mariadb来启动数据库,systemctl star ...
- MinIO客户端之diff
MinIO提供了一个命令行程序mc用于协助用户完成日常的维护.管理类工作. 官方资料 mc diff 检查指定桶内对象清单的差异,注意不比较对象内容的差异,命令如下: ./mc diff local1 ...
- Python——第五章:os模块、sys模块
os 模块 os 模块提供了很多允许你的程序与操作系统直接交互的功能 import os 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目 ...
- Windows Server 2012 R2在桌面上显示我的电脑等图标
从Windows 2012 开始,微软取消了服务器桌面个性化选项,如何重新调出配置界面,可以使用微软命令.方法如下: 按下「Win鍵」+「R」,在运行里输入: rundll32.exe shell3 ...