本文主要介绍基于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语义化版本规范(详见:https://semver.org/)。

解析算法

package-lock.json

package-lock.json是在npm install时自动生成的文件,用以记录当前状态下实际安装的各个npm package的具体来源和版本号,通过该文件可以准确定位到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。

<package-lock.json文件结构>可看出组件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官网

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

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

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。

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

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

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

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


OpenSCA已在GitHub和Gitee开源,欢迎Star和PR,成为我们的开源贡献者,也可提交问题或建议至Issues。我们会参考大家的建议不断完善OpenSCA开源项目,敬请期待更多功能的支持。

GitHub: https://github.com/XmirrorSecurity/OpenSCA-cli/releases

Gitee: https://gitee.com/XmirrorSecurity/OpenSCA-cli/releases

OpenSCA官网: https://opensca.xmirror.cn/

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

 
 

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

  1. Atitit usrQBK1600 技术文档的规范标准化解决方案

    Atitit usrQBK1600 技术文档的规范标准化解决方案 1.1. Keyword关键词..展关键词,横向拓展比较,纵向抽象细化拓展知识点1 1.2. 标题必须有高大上词汇,参考文章排行榜,1 ...

  2. Kafka 技术文档

    Kafka 技术文档   目录 1 Kafka创建背景 2 Kafka简介 3 Kafka好处 3.1 解耦 3.2 冗余 3.3 扩展性 3.4 灵活性 & 峰值处理能力 3.5 可恢复性 ...

  3. 使用Jupyter Notebook编写技术文档

    1.jupyter Notebook的组成 这里它的组件及其工程构成,帮助大家更好的用好jupyter Notebook 组件 Jupyter Notebook结合了三个组件: 笔记本Web应用程序: ...

  4. 如何写好技术文档——来自Google十多年的文档经验

    本文大部分内容翻译总结自<Software Engineering at Google> 第10章节 Documentation. 另外,该书电子版近日已经可以免费下载了 https:// ...

  5. RabbitMq 技术文档

    RabbitMq 技术文档 目录 1 AMQP简介 2 AMQP的实现 3 RabbitMQ简介 3.1 概念说明 3.2 消息队列的使用过程 3.3 RabbitMQ的特性 4 RabbitMQ使用 ...

  6. [转]unity3d 脚本参考-技术文档

    unity3d 脚本参考-技术文档 核心提示:一.脚本概览这是一个关于Unity内部脚本如何工作的简单概览.Unity内部的脚本,是通过附加自定义脚本对象到游戏物体组成的.在脚本对象内部不同志的函数被 ...

  7. Umbraco官方技术文档 中文翻译

    Umbraco 官方技术文档中文翻译 http://blog.csdn.net/u014183619/article/details/51919973 http://www.cnblogs.com/m ...

  8. [转]chrome技术文档列表

    chrome窗口焦点管理系统 http://www.douban.com/note/32607279/ chrome之TabContents http://www.douban.com/note/32 ...

  9. Niagara技术文档汇总

    Niagara技术文档汇总http://wenku.baidu.com/view/ccdd4e2c3169a4517723a38f.html Niagara讲解要点http://wenku.baidu ...

  10. DL动态载入框架技术文档

    DL动态载入框架技术文档 DL技术交流群:215680213 1. Android apk动态载入机制的研究 2. Android apk动态载入机制的研究(二):资源载入和activity生命周期管 ...

随机推荐

  1. 【Codeforces Global Round 12】 C2 - Errich-Tac-Toe题解(思维)

    题面 题目要求不能有有三个连续相同的'X'或'O',注意到这样的连续串它们的横纵坐标之和是连续变化的,考虑将它们按照横纵坐标之和对 \(3\)的模值分组,因为这样分组后相邻的三个相同字符就被分到了三个 ...

  2. kotlin+springboot入门级别教程,教你如何用kotlin和springboot搭建http

    先打开idea,或者用springboot官网.阿里云那边都行 然后点击新建项目,spring Initializr,我们都知道,springboot是支持kotlin的,除非你是kotlin1.3之 ...

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

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

  4. 一行代码修复100vh bug | 京东云技术团队

    你知道奇怪的移动视口错误(也称为100vh bug)吗?或者如何以正确的方式创建全屏块? 一.100vh bug 什么是移动视口错误? 你是否曾经在网页上创建过全屏元素?只需添加一行 CSS 并不难: ...

  5. java通过url得到文件对象(支持http和https)

    文字标题:java通过url得到文件对象(支持http和https) 作者:锅巴 1.场景:通过一个url地址来得到一个文件,此方式就是通过一个url将文件下载到本地的临时文件,直接上代码 /** * ...

  6. Python笔记二之多线程

    本文首发于公众号:Hunter后端 原文链接:Python笔记二之多线程 这一篇笔记介绍一下在 Python 中使用多线程. 注意:以下的操作都是在 Python 3.8 版本中试验,不同版本可能有不 ...

  7. 基于Docker 部署 Seafile+OnlyOffice+Wiki插件

    原文:基于 Docker 部署 SeafilePro + OnlyOffice(CentOS版) 官方文档:用 Docker 部署 Seafile 服务 CentOS 服务器 基于 Docker 部署 ...

  8. Python——第一章:注释、变量、常量

    python中的注释有2种: 1.单行注释 单行注释用# #这是一个单行注释 快捷键用Ctrl+/全选多个内容可以多行快速注释,也可以快速去掉注释符# 比如快速将全选的所有行注释掉--加# 2.多行注 ...

  9. React jsx 语法解析 & 转换原理

    jsx介绍 jsx是一种JavaScript的语法扩展(eXtension),也在很多地方称之为JavaScript XML,因为看起就是一段XML语法,用于描述UI界面,并且可以和JavaScrip ...

  10. three.js中场景模糊、纹理失真的问题

    目录 1. 概述 2. 方案 2.1. 开启反走样 2.2. 开启HiDPI设置 3. 结果 4. 参考 1. 概述 在three.js场景中,有时会遇到场景模糊,纹理失真的现象,似乎three.js ...