網站導覽
目錄
相依性選擇器語法和查詢
選擇 CLI 版本
目錄
說明
npm query
指令公開了新的相依性選擇器語法(根據 CSS 選擇器 4 規範 的許多面向提供資訊並予以尊重),其中
- 透過強健的物件模型、元資料和選擇器語法,標準化相依性圖形的形狀和查詢
- 利用現有的已知語言語法和 CSS 的運算子,讓不同的套件資訊廣泛地被存取
- 解鎖回答關於相依性、其關係和關聯元資料的複雜且多面向問題的能力
- 整合
npm
中類似查詢指令的重複邏輯(例如npm fund
、npm ls
、npm outdated
、npm audit
...)
相依性選擇器語法
概觀
- 沒有「類型」或「標籤」選取器(例如
div, h1, a
),因為相依關係/目標是唯一可以查詢的Node
類型 - 「相依關係」一詞是指
Arborist
傳回的tree
中找到的任何Node
組合器
>
直接後代/子項任何後代/子項
~
同層
選擇器
*
萬用選取器#<name>
相依關係選取器(等同於[name="..."]
)#<name>@<version>
(等同於[name=<name>]:semver(<version>)
),
選取器清單分隔符號.
相依關係類型選取器:
偽選取器
相依性類型選擇器
.prod
在package.json
的dependencies
區段中找到的相依關係,或為該相依關係的子項.dev
在package.json
的devDependencies
區段中找到的相依關係,或為該相依關係的子項.optional
在package.json
的optionalDependencies
區段中找到的相依關係,或在package.json
的peerDependenciesMeta
區段中其項目設定"optional": true
,或為該相依關係的子項.peer
在package.json
的peerDependencies
區段中找到的相依關係.workspace
在package.json
的workspaces
區段中找到的相依關係.bundled
在package.json
的bundleDependencies
區段中找到的相依關係,或為該相依關係的子項
偽選擇器
:not(<selector>)
:has(<selector>)
:is(<selector list>)
:root
符合根節點/依賴項:scope
符合針對其執行查詢的節點/依賴項:empty
當依賴項沒有任何依賴項時:private
當依賴項為私有時:link
當依賴項已連結(例如,工作區或手動連結的套件linked
:deduped
當依賴項已重複刪除(請注意,這並不總是表示依賴項已被提升至 node_modules 的根目錄):overridden
當依賴項已被覆寫時:extraneous
當依賴項存在,但未定義為任何節點的依賴項時:invalid
當依賴項版本超出其祖先指定的範圍時:missing
當在磁碟上找不到依賴項時:semver(<spec>, [selector], [function])
將有效的node-semver
版本或範圍符合選取器:path(<path>)
glob 根據依賴項相對於專案的路徑進行比對:type(<type>)
根據目前識别的類型:outdated(<type>)
當依賴項已過時時:vuln(<selector>)
當依賴項具有已知的漏洞時
:semver(<spec>, [selector], [function])
偽選取器 :semver()
允許使用 semver 方法,比較每個節點的 package.json
中的欄位。它最多接受 3 個參數,除了第一個參數之外,其餘都是選用的。
spec
semver 版本或範圍selector
針對每個節點的屬性選取器(預設[version]
)function
要套用的 semver 方法,其中之一:satisfies
、intersects
、subset
、gt
、gte
、gtr
、lt
、lte
、ltr
、eq
、neq
或特殊函式infer
(預設infer
)
當使用特殊函式 infer
時,會比較 spec
和節點中的實際值。如果兩者都是版本,根據 semver.valid()
,會使用 eq
。如果兩個值都是範圍,根據 !semver.valid()
,會使用 intersects
。如果值是混合類型,會使用 satisfies
。
一些範例
:semver(^1.0.0)
會傳回每個具有版本^1.0.0
範圍所滿足的version
的節點:semver(16.0.0, :attr(engines, [node]))
會傳回每個具有滿足版本16.0.0
的engines.node
屬性的節點:semver(1.0.0, [version], lt)
每個具有小於1.0.0
的version
的節點
:outdated(<type>)
偽選取器 :outdated
會從註冊中心擷取資料,並傳回關於哪些依賴項已過期的資訊。類型參數可以是下列其中之一
any
(預設)存在大於目前版本in-range
存在大於目前版本,且滿足至少一個其父系依賴項的版本out-of-range
存在大於目前版本,且不滿足至少一個其父系依賴項的版本major
有個版本存在,其 semver major 大於目前的版本minor
有個版本存在,其 semver minor 大於目前的版本patch
有個版本存在,其 semver patch 大於目前的版本
除了偽選取器執行的過濾之外,還會將一些額外資料新增到結果物件。下列資料可以在每個節點的 queryContext
屬性中找到。
versions
給定節點的每個可用版本的陣列outdated.inRange
物件陣列,每個物件都有from
和versions
,其中from
是依賴於目前節點的節點的磁碟位置,而versions
是滿足該相依性的所有可用版本的陣列。這只有在使用:outdated(in-range)
時才會填充。outdated.outOfRange
物件陣列,其形狀與inRange
相同,但versions
陣列是不滿足相依性的每個可用版本。這只有在使用:outdated(out-of-range)
時才會填充。
一些範例
:root > :outdated(major)
傳回每個具有新的 semver major 版本的直接相依性.prod:outdated(in-range)
傳回具有新版本的生產相依性,該新版本滿足其父項相依性的其中一個以上
:vuln
:vuln
偽選取器會從註冊表中擷取資料,並傳回有關您的相依性是否有已知弱點的資訊。只有其目前版本符合弱點的相依性才會傳回。例如,如果您的樹狀結構中有 semver@7.6.0
,則會影響版本 <=6.3.1
的 semver
弱點將不會符合。
您也可以根據建議中的特定屬性來過濾結果。目前包括 severity
和 cwe
。請注意,嚴重性過濾是針對每個嚴重性進行,它不包含比指定的嚴重性「更高」或「更低」的嚴重性。
除了偽選取器執行的過濾之外,每個相關建議的資訊會新增到每個節點的 queryContext
屬性,位於 advisories
屬性之下。
一些範例
:root > .prod:vuln
傳回具有任何已知弱點的直接生產相依性:vuln([severity=high])
僅傳回具有嚴重性為high
的漏洞之相依性。:vuln([severity=high],[severity=moderate])
僅傳回具有嚴重性為high
或moderate
的漏洞之相依性。:vuln([cwe=1333])
僅傳回具有包含 CWE-1333 (ReDoS) 的漏洞之相依性。
屬性選擇器
屬性選擇器會評估 package.json
中的鍵/值配對,如果它們是 String
。
[]
屬性選擇器(即屬性存在)[attribute=value]
屬性值等於...[attribute~=value]
屬性值包含字詞...[attribute*=value]
屬性值包含字串...[attribute|=value]
屬性值等於或開頭為...[attribute^=value]
屬性值開頭為...[attribute$=value]
屬性值結尾為...
Array
和 Object
屬性選擇器
通用 :attr()
偽選擇器標準化一種模式,可用於選擇 Object
、Array
或 Object
的 Array
,這些可透過 Arborist
的 Node.package
元資料存取。這允許進行超越頂層 String
評估的迭代屬性選擇。傳遞給 :attr()
的最後一個引數必須是 attribute
選擇器或巢狀 :attr()
。請參閱以下範例
物件
/* return dependencies that have a `scripts.test` containing `"tap"` */*: attr(scripts, [test~=tap]);
巢狀 Objects
巢狀物件表示為 :attr()
的順序引數。
/* return dependencies that have a testling config for opera browsers */*: attr(testling, browsers, [~=opera]);
陣列
Array
特別使用特殊/保留的 .
字元來取代典型的屬性名稱。當 String
傳遞給選擇器時,Array
也支援精確 value
比對。
範例:陣列
屬性選取
/* removes the distinction between properties & arrays *//* ie. we'd have to check the property & iterate to match selection */*:attr([keywords^=react])*:attr(contributors, :attr([name~=Jordan]))
範例:陣列
直接比對值
/* return dependencies that have the exact keyword "react" *//* this is equivalent to `*:keywords([value="react"])` */*: attr([keywords=react]);
範例:陣列
的物件
/* returns */*: attr(contributors, [email=ruyadorno @github.com]);
群組
相依群組是由套件與其祖先的關係所定義(亦即在package.json
中定義的相依類型)。這種做法以使用者為中心,因為生態系統已教導使用者優先考慮這些群組中的相依性。相依性允許包含在多個群組中(例如:prod
相依性也可能是dev
相依性(因為它也需要另一個dev
相依性),也可能是bundled
- 這種相依性的選取器看起來像這樣:*.prod.dev.bundled
)。
.prod
.dev
.optional
.peer
.bundled
.workspace
請注意,目前workspace
相依性總是prod
相依性。此外,.root
相依性也視為prod
相依性。
程式化使用
Arborist
的Node
類別有一個.querySelectorAll()
方法- 此方法會根據有效的查詢選取器,傳回經過篩選、扁平化的相依性Arborist
Node
清單
- 此方法會根據有效的查詢選取器,傳回經過篩選、扁平化的相依性Arborist
const Arborist = require("@npmcli/arborist");const arb = new Arborist({});
// root-levelarb.loadActual().then(async (tree) => {// query all production dependenciesconst results = await tree.querySelectorAll(".prod");console.log(results);});
// iterativearb.loadActual().then(async (tree) => {// query for the deduped version of reactconst results = await tree.querySelectorAll("#react:not(:deduped)");// query the deduped react for git depsconst deps = await results[0].querySelectorAll(":type(git)");console.log(deps);});