2013-03-02 131 views
45

有沒有一種方法可以在npm package.json文件中指定操作系統特定的依賴關係?npm package.json操作系統特定的依賴關係

例如,如果用戶正在運行Linux,我只想安裝'dbus'(https://npmjs.org/package/dbus)作爲我的模塊的依賴項。我對Mac和Windows會有不同的依賴關係。

+5

好問題。我知道[package.json](https://npmjs.org/doc/json.html)中有'os'字段,但是這不允許您在當前平臺上交換依賴關係 - 它只是聲明哪些平臺被列入白名單/列入黑名單。 例如,這個屬性在'package.json': ' 「OS」: 「!win32的」, 「達爾文」]' 的意思是 「這個軟件包將無法在Windows上運行,但在Mac電腦上運行」。不幸的是,這並沒有真正實現你所要求的。 – smithclay 2013-03-05 18:29:51

+0

^這正是問題所在,如果dbus模塊具有隻能在特定操作系統上編譯的本地綁定([在註釋中提到](http://stackoverflow.com/questions/15176082/npm-package-json- os-specific-dependency#comment22801812_15670089)),它的package.json應該包含'os'字段。 – 2014-07-16 19:31:15

回答

25

根據您的設置,可能有這樣做的好方法。

NPM的package.json支持一個os鍵,

並且還optionalDependencies

  • os可以被用來指定一個模塊可以安裝在其上的操作系統。
  • optionalDependencies是模塊依賴關係,如果無法安裝,npm會跳過它們並繼續安裝。

通過這種方式,你可以有你的模塊爲每個OS的可選的依賴,而只有其中一個作品將被載入/安裝^^

編輯:作爲@Sebastien以下提到, 這種做法很危險。 對於任何給定的操作系統,至少有一個依賴關係是「必需的」,其餘的是「可選的」。使所有版本的依賴項可選意味着,如果您的安裝由於合法原因而失敗,它將默默跳過安裝,並且您將錯過您真正需要的依賴項。

+2

剛剛找到了這個答案(在回覆您對反模式的評論之後)。這看起來比使用安裝腳本更好的解決方案!現在,我知道這是可用的,你可以忽略我的評論(我會嘗試刪除/編輯它,如果它不是太晚) – Metalskin 2014-11-25 05:42:14

+0

我有點希望我也可以刪除我的評論,因爲我最終使用安裝腳本,大量用這個解決方案>< – TinyTimZamboni 2015-01-09 08:49:49

+0

你能告訴我一個完整的例子嗎?說'fsevents'是可選的依賴於OSX,我不在乎,因爲我的構建腳本在LINUX上運行。 – 2015-09-08 06:47:03

6

我認爲簡短的答案是否定的。但我可以想到幾個解決方法 - 最簡單的方法就是將所有內容添加到package.json中,而不管操作系統是什麼,然後在運行時將其正確添加到require()

如果不爲你工作,你可能能夠使用一個安裝腳本,讓你要去的結果 - https://docs.npmjs.com/misc/scripts

我沒有測試過這一點,但我認爲這是可行的:

添加像這樣到你的package.json:

,"scripts": { 
    "install": "node install_dependencies.js" 
} 

,然後添加一個install_dependencies.js文件檢查操作系統,並運行相應的npm install ...命令。

+5

問題是我的依賴項具有隻在特定操作系統上編譯的本地綁定,所以我不能將它們作爲顯式依賴項。您對npm install腳本的建議可行,我使用os.platform()來檢測用戶正在使用哪個平臺; – sandeepmistry 2013-04-13 20:28:14

+2

安裝腳本現在被認爲是'反模式'[源](https://www.npmjs.org/doc/misc/npm-scripts.html#note-install-scripts-are-an-antipattern)。相反應該使用.gyp編譯文件 – TinyTimZamboni 2014-09-26 23:35:46

+1

只是一個觀察,我不明白與上述。如果使用'package.json'來管理項目的安裝而不是發佈,那麼使用.gyp不是解決方案。請參閱下面的TinyTimZamboni文章,它更適合這種情況(http://stackoverflow.com/a/26069595/1125784)。 – Metalskin 2014-11-25 05:44:42

1

另外還有綁定,shyp模塊:

https://www.npmjs.com/package/bindings-shyp

加載你的本機模塊的.node文件助手模塊

這是節點的作者的輔助模塊.js原生插件模塊。它基本上是require()你的本地模塊的.node文件的「瑞士軍刀」。

整個節點的本地插件歷史的長河中,插件已經結束了在各種不同的地方被編譯,這取決於構建工具和使用節點的版本。更糟糕的是,現在gyp構建工具可以生成Release或Debug構建版本,每個構建到不同的位置。

該模塊檢查所有本地插件將在建的可能位置,並返回成功加載的第一個。

0

在競標@npm_support:

https://twitter.com/npm_support/status/968195526989512705

2/2如果你想避免與依賴關係安裝的問題,一條路徑是爲你寫的需要的是一個包裝一個常規的依賴關係,並確保它具有optionalDeps(並確保包裝器驗證您擁有所需的所有工作)。

但恕我直言,它看起來更像是一個解決辦法,而不是解決真正的問題。

我可以理解,npm希望保留可移植性並避免處理特定於平臺的問題,但無論如何它必須完成,並且恕我直言在運行時執行此操作並不是最佳(專業如果需要優化代碼大小)。

所以今天我也沒有最佳的解決方案,分享,但對提案的公開討論。

不能「條件依賴」被在NPM支持?

是來到我的腦海的第一個事情就是添加一個「覆蓋」節會改變(+增加,-remove,=替換)當前解析的部分。

例如:

dependencies: { "common-stuff": "*" } overrides: { "os: { linux: { dependencies: { "+best-linux-module" } } } }

與其他選項可以通過我認識的一個開發商建議,將引入提供關鍵字,然後幾個模塊可以提供相同的語義比通過分解得到滿足(a debian),但它產生了類似的開銷。

我要尋找一個通用的方法並不只專注於操作系統的支持也是對包裝的其他口味(取決於發動機爲例)。

您是否知道NPM跟蹤器中的任何相關問題?

https://github.com/npm/npm/issues?q=dependencies+conditional

反饋歡迎這一想法:如果沒有我正在考慮提交一份錯誤在被跟蹤。