OpenSCA技術(shù)原理npm依賴(lài)示例解析
npm介紹
本文主要介紹基于npm包管理器的組件成分解析原理。
npm(全稱(chēng)Node Package Manager)是Node.js標(biāo)準(zhǔn)的軟件包管理器。
npm的依賴(lài)管理文件是package.json,開(kāi)發(fā)者可以在package.json中指定每個(gè)依賴(lài)項(xiàng)的版本范圍。
如果一個(gè)項(xiàng)目中存在package.json文件,便可以執(zhí)行npm install命令自動(dòng)安裝和維護(hù)當(dāng)前項(xiàng)目所需的所有模塊并生成package-lock.json文件。
package.json完整文件結(jié)構(gòu)如下:
{
"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為項(xiàng)目名,version為項(xiàng)目版本,license為項(xiàng)目聲明的許可證,devDependencies為開(kāi)發(fā)環(huán)境使用的依賴(lài),dependencies為生產(chǎn)環(huán)境使用的依賴(lài)。
依賴(lài)寫(xiě)法為"name":"version",版本可以指定準(zhǔn)確版本或一個(gè)范圍,范圍需遵循semver語(yǔ)義化版本規(guī)范
解析算法
package-lock.json
package-lock.json是在npm install時(shí)自動(dòng)生成的文件,用以記錄當(dāng)前狀態(tài)下實(shí)際安裝的各個(gè)npm package的具體來(lái)源和版本號(hào),通過(guò)該文件可以準(zhǔn)確定位到npm項(xiàng)目的依賴(lài)及版本。所以?xún)?yōu)先解析package-lock.json文件。
package-lock.json文件結(jié)構(gòu)如下:
{
"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字段為項(xiàng)目名稱(chēng),version字段為項(xiàng)目版本。dependencies字段中包含項(xiàng)目使用的所有直接和間接依賴(lài),而且記錄了組件間的依賴(lài)關(guān)系。
例如:
"b": {
"version": "1.2.1"
},
代表組件b的版本號(hào)為1.2.1。
"a": {
"version": "2.1.5",
"requires": {
"b": "^1.1.9"
}
},
代表項(xiàng)目依賴(lài)2.1.5版本的組件a,該組件依賴(lài)版本約束為^1.1.9的組件b。
同理可知項(xiàng)目依賴(lài)1.3.1版本的組件c,該組件依賴(lài)版本約束為^1.2.0的組件b。
從 <package-lock.json文件結(jié)構(gòu)> 可看出組件a和組件c都沒(méi)有被其他組件所依賴(lài),所以可知這兩個(gè)組件是項(xiàng)目的直接依賴(lài)。
僅通過(guò)package-lock.json無(wú)法確定組件b是否是直接依賴(lài),可以結(jié)合package.json文件進(jìn)一步確定,沒(méi)有package.json時(shí),將b當(dāng)作間接依賴(lài)處理。若一個(gè)組件同時(shí)為直接和間接依賴(lài),按直接依賴(lài)處理。
注:
- ^1.1.9代表版本號(hào)需要>=1.1.9且<2.0.0;
- ^1.2.0代表版本號(hào)需要>=1.2.0且<2.0.0;
- 更多約束格式請(qǐng)參閱semver官網(wǎng)
由此可以構(gòu)建出當(dāng)前項(xiàng)目的依賴(lài)結(jié)構(gòu):

實(shí)線代表直接依賴(lài),虛線代表間接依賴(lài)。
package.json
package.json為開(kāi)發(fā)者編寫(xiě)管理的依賴(lài)管理文件,在未找到package-lock.json文件時(shí)將解析該文件。
package.json僅包含直接依賴(lài),在項(xiàng)目構(gòu)建時(shí)會(huì)從npm倉(cāng)庫(kù)下載需要的間接依賴(lài)并構(gòu)建為package-lock.json文件,因此可以模擬npm構(gòu)建流程來(lái)獲取項(xiàng)目引用的組件依賴(lài)。
package.json文件結(jié)構(gòu)如下:
{
"name": "foo",
"version": "1.0.0",
"devDependencies": {
"a": "^2.0.0"
},
"dependencies": {
"c": "^1.1.0"
}
}
dependencies為項(xiàng)目實(shí)際使用的直接依賴(lài),devDependencies為項(xiàng)目開(kāi)發(fā)時(shí)使用的直接依賴(lài)。
例如:
"devDependencies": {
"a": "^2.0.0"
}
代表項(xiàng)目開(kāi)發(fā)過(guò)程中依賴(lài)版本約束為^2.0.0的組件a。
"dependencies": {
"c": "^1.1.0"
}
代表項(xiàng)目直接依賴(lài)版本約束為^1.1.0組件c。
分析到這里我們可以總結(jié)出如下圖依賴(lài)關(guān)系:

通過(guò)該依賴(lài)關(guān)系可以看出項(xiàng)目組件的直接依賴(lài)及組件的版本范圍,但無(wú)法得知組件依賴(lài)的具體版本。
在沒(méi)有package-lock.json文件的情況下,為了進(jìn)一步獲取依賴(lài)的準(zhǔn)確版本及間接依賴(lài),需要從npm倉(cāng)庫(kù)下載對(duì)應(yīng)組件的詳細(xì)信息。
例如組件a的詳細(xì)信息結(jié)構(gòu)為:
{
"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字段為組件所有版本及發(fā)布日期,根據(jù)約束從這里獲取約束范圍內(nèi)的最大版本。
versions字段為組件各個(gè)版本對(duì)應(yīng)的詳細(xì)信息,其中dependencies字段為組件的依賴(lài)信息。
對(duì)于本例來(lái)說(shuō),組件a的約束為^2.0.0,要求版本號(hào)>=2.0.0且<3.0.0,所以選擇2.1.5版本。因此組件依賴(lài)結(jié)構(gòu)就變成了:

按照這種方式層級(jí)解析便可獲取整個(gè)項(xiàng)目的依賴(lài)信息。
感謝每一位開(kāi)源社區(qū)成員對(duì)OpenSCA的支持和貢獻(xiàn)。
OpenSCA已在GitHub和Gitee開(kāi)源,歡迎Star和PR,成為我們的開(kāi)源貢獻(xiàn)者,也可提交問(wèn)題或建議至Issues。我們會(huì)參考大家的建議不斷完善OpenSCA開(kāi)源項(xiàng)目,敬請(qǐng)期待更多功能的支持。
OpenSCA官網(wǎng):
opensca.xmirror.cn/
GitHub:
github.com/XmirrorSecu…
Gitee:
gitee.com/XmirrorSecu…。
以上就是OpenSCA技術(shù)原理npm依賴(lài)示例解析的詳細(xì)內(nèi)容,更多關(guān)于OpenSCA技術(shù)npm依賴(lài)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
node使用require?mkdirp創(chuàng)建文件夾示例
這篇文章主要為大家介紹了node使用require?mkdirp創(chuàng)建文件夾示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
NodeJS多種創(chuàng)建WebSocket監(jiān)聽(tīng)的方式(三種)
這篇文章主要介紹了NodeJS多種創(chuàng)建WebSocket監(jiān)聽(tīng)的方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
node.js中的http.request方法使用說(shuō)明
這篇文章主要介紹了node.js中的http.request方法使用說(shuō)明,本文介紹了http.request的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼需要的朋友可以參考下2014-12-12
nestjs中異常過(guò)濾器Exceptionfilter的具體使用
這篇文章主要介紹了nestjs中異常過(guò)濾器Exceptionfilter的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
NodeJS實(shí)現(xiàn)視頻轉(zhuǎn)碼的示例代碼
本篇文章主要介紹了NodeJS實(shí)現(xiàn)視頻轉(zhuǎn)碼的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
node使用promise替代回調(diào)函數(shù)
這篇文章主要介紹了node使用promise替代回調(diào)函數(shù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
詳解express使用vue-router的history踩坑
這篇文章主要介紹了express 使用 vue-router 的 history 踩坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

