简体   繁体   English

npm package.json OS特定依赖项

[英]npm package.json OS specific dependency

Is there a way to specify OS specific dependencies in a npm package.json file? 有没有办法在npm package.json文件中指定操作系统特定的依赖项?

For example, I would only want to install 'dbus' ( https://npmjs.org/package/dbus ) as a dependency for my module if the user is running Linux. 例如,如果用户运行Linux,我只想安装'dbus'( https://npmjs.org/package/dbus )作为我模块的依赖项。 I would have a different dependency for Mac and Windows. 我对Mac和Windows有不同的依赖。

There's a possible good way of doing this, depending on your setup. 根据您的设置,这可能是一种很好的方法。

npm package.json supports an os key, npm package.json支持os密钥,

and also optionalDependencies 以及optionalDependencies

  • os can be used to specify which OS a module can be installed on. os可用于指定可以安装模块的OS。
  • optionalDependencies are module dependencies that if they cannot be installed, npm skips them and continues installing. optionalDependencies是模块依赖项,如果它们无法安装,npm会跳过它们并继续安装。

In this way you can have your module have an optional dependency for each OS, and only the one which works will be loaded/installed ^.^ 通过这种方式,您可以让您的模块对每个操作系统具有可选的依赖关系,并且只有加载/安装的模块才会被加载/安装^。^

EDIT: As @Sebastien mentions below, this approach is dangerous . 编辑:正如@Sebastien在下面提到的, 这种方法很危险 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. 使所有版本的依赖项可选意味着如果您的安装因合法原因而失败,它将默默地跳过安装,您将缺少您真正需要的依赖项。

I think the short answer is no. 我认为简短的回答是否定的。 I can think of a couple of workarounds though - the simplest is to just add everything to package.json regardless of OS, and then require() the correct one at runtime. 我可以想到几个解决方法 - 最简单的方法是将所有内容添加到package.json而不管操作系统,然后在运行时require()正确的一个。

If that doesn't work for you, you might be able to use an install script to get the result you're going for - https://docs.npmjs.com/misc/scripts 如果这对您不起作用,您可以使用安装脚本来获得您想要的结果 - https://docs.npmjs.com/misc/scripts

I haven't tested this but I think it would work: 我没有测试过这个,但我认为它会起作用:

Add something like this to your package.json: 将这样的内容添加到package.json中:

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

And then add a install_dependencies.js file that checks the OS and runs the appropriate npm install ... commands. 然后添加一个install_dependencies.js文件来检查操作系统并运行相应的npm install ...命令。

There's also the bindings-shyp module: 还有绑定-shyp模块:

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

Helper module for loading your native module's .node file Helper模块,用于加载本机模块的.node文件

This is a helper module for authors of Node.js native addon modules. 这是Node.js本机插件模块的作者的辅助模块。 It is basically the "swiss army knife" of require()ing your native module's .node file. 它基本上是require()你的本机模块的.node文件的“瑞士军刀”。

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. 在Node的本机插件历史过程中,插件最终在各种不同的位置进行编译,具体取决于使用的构建工具和节点版本。 To make matters worse, now the gyp build tool can produce either a Release or Debug build, each being built into different locations. 更糟糕的是,现在gyp构建工具可以生成Release或Debug构建,每个构建都构建在不同的位置。

This module checks all the possible locations that a native addon would be built at, and returns the first one that loads successfully. 此模块检查将在其中构建本机插件的所有可能位置,并返回第一个成功加载的位置。

Quoting @npm_support at: 引用@npm_support:

https://twitter.com/npm_support/status/968195526989512705 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). 2/2如果你想避免与依赖关系相关的安装问题,你可以编写一个路由来编写一个需要作为常规依赖项的包装器,并确保它具有optionalDeps (并且还要确保包装器验证你有一切都需要工作)。

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). 我可以理解,npm希望保留可移植性并避免处理平台细节,但无论如何必须完成它并且IMHO在运行时执行此操作并不是最佳的(如果想要优化代码大小,那就是专业)。

So today I have no optimal solution to share but an open discussion for proposal. 所以今天我没有最佳的解决方案来分享,而是公开讨论提案。

Can't "conditional dependencies" be supported in npm ? 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. 我想到的第一件事是添加一个“覆盖”部分,它将改变(+ add,-remove,= replace)当前解析的部分。

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). 我正在寻找一种通用的方法,不仅关注OS支持,还关注其他类型的包(例如,取决于引擎)。

Do you know any related issue in NPM tracker ? 您知道NPM跟踪器中的任何相关问题吗? if not I am considering to file a bug to be tracked at: 如果没有,我正在考虑提交一个要跟踪的错误:

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

Feedback welcome on this idea. 欢迎对这个想法的反馈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM