69

有没有办法在 npm package.json 文件中指定操作系统特定的依赖项?

例如,如果用户正在运行 Linux,我只想安装 'dbus' ( https://npmjs.org/package/dbus ) 作为我的模块的依赖项。我对 Mac 和 Windows 会有不同的依赖。

4

4 回答 4

41

有一种可能的好方法可以做到这一点,具体取决于您的设置。

npm package.json 支持os密钥,

还有可选的依赖项

  • os可用于指定模块可以安装在哪个操作系统上。
  • optionalDependencies是模块依赖项,如果无法安装,npm 会跳过它们并继续安装。

通过这种方式,您可以让您的模块对每个操作系统都有一个可选的依赖项,并且只有可以加载/安装的模块才会被加载/安装 ^.^

EDIT: As @Sebastien mentions below, this approach is dangerous. For any given OS, at least one of your dependencies is "required" and the rest "optional". Making all versions of the dependency optional means that if your installation fails for a legitimate reason, it will silently skip installation and you will be missing a dependency you really need.

于 2014-09-26T23:14:52.397 回答
9

我认为简短的回答是否定的。不过,我可以想到几种解决方法——最简单的方法是将所有内容添加到 package.json 中,而不管操作系统如何,然后require()在运行时添加正确的内容。

如果这对您不起作用,您也许可以使用安装脚本来获得您想要的结果 - https://docs.npmjs.com/misc/scripts

我没有对此进行测试,但我认为它会起作用:

在你的 package.json 中添加这样的内容:

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

然后添加一个install_dependencies.js检查操作系统并运行相应npm install ...命令的文件。

于 2013-03-27T21:42:19.060 回答
1

There's also the bindings-shyp module:

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

Helper module for loading your native module's .node file

This is a helper module for authors of Node.js native addon modules. It is basically the "swiss army knife" of require()ing your native module's .node file.

Throughout the course of Node's native addon history, addons have ended up being compiled in a variety of different places, depending on which build tool and which version of node was used. To make matters worse, now the gyp build tool can produce either a Release or Debug build, each being built into different locations.

This module checks all the possible locations that a native addon would be built at, and returns the first one that loads successfully.

于 2014-09-26T23:37:15.890 回答
1

Quoting @npm_support at:

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

2/2 If you'd like to avoid installation problems related to dependencies, one route is for you to write a wrapper that's required as a regular dependency, and to make sure that it has optionalDeps (and also ensure that the wrapper verifies you have everything needed to work).

But IMHO it looks more like a workaround than solving the problem for real.

I can understand that npm wants to preserve portability and avoid to deal with platform specifics, but it has to be done anyway and IMHO doing this at runtime is not optimal (specialty if one wants do optimize code size).

So today I have no optimal solution to share but an open discussion for proposal.

Can't "conditional dependencies" be supported in npm ?

The 1st thing that came to my mind was to to add a "override" section that will change (+add, -remove, =replace) current parsed sections.

For example:

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

And other option suggested by a developer I know, would be to introduce a provides keyword, then several modules could provide a same semantic than would be satisfied by resolver (a la debian), but it's generating similar overhead.

I am looking for a generic approach not only focused on OS support but also on other flavors of package (depending on engines for instance).

Do you know any related issue in NPM tracker ? if not I am considering to file a bug to be tracked at:

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

Feedback welcome on this idea.

于 2018-02-26T17:23:39.900 回答