有没有办法在 npm package.json 文件中指定操作系统特定的依赖项?
例如,如果用户运行的是 Linux,我只想安装“dbus”(https://npmjs.org/package/dbus)作为我的模块的依赖项。我对 Mac 和 Windows 有不同的依赖关系。
有一种可能的好方法可以做到这一点,具体取决于您的设置。
npm package.json 支持 os 键,
还有可选依赖项
os
可用于指定模块可以安装在哪个操作系统上。optionalDependencies
是模块依赖项,如果无法安装,npm 会跳过它们并继续安装。通过这种方式,您可以让您的模块对每个操作系统都有一个可选的依赖项,并且只有有效的才会被加载/安装^.^
编辑: 正如@Sebastien 下面提到的,这种方法很危险。 对于任何给定的操作系统,至少有一个依赖项是“必需的”,其余的则是“可选的”。将所有版本的依赖项设置为可选意味着,如果您的安装因正当原因失败,它将默默地跳过安装,并且您将丢失真正需要的依赖项。
我认为简短的答案是否定的。不过,我可以想到几种解决方法 - 最简单的是将所有内容添加到 package.json,无论操作系统如何,然后
require()
在运行时正确的解决方法。
如果这对您不起作用,您也许可以使用安装脚本来获得您想要的结果 - https://docs.npmjs.com/misc/scripts
我还没有测试过这个,但我认为它会起作用:
将这样的内容添加到你的 package.json 中:
,"scripts": {
"install": "node install_dependencies.js"
}
然后添加一个
install_dependencies.js
文件来检查操作系统并运行适当的 npm install ...
命令。
还有 bindings-shyp 模块:
https://www.npmjs.com/package/bindings-shyp
用于加载本机模块的 .node 文件的帮助模块
这是 Node.js 原生插件模块作者的帮助模块。它基本上是 require() 原生模块的 .node 文件的“瑞士军刀”。
在 Node 原生插件的历史过程中,插件最终被编译在各种不同的地方,具体取决于使用的构建工具和节点版本。更糟糕的是,现在 gyp 构建工具可以生成发布或调试构建,每个构建都构建到不同的位置。
此模块检查构建本机插件的所有可能位置,并返回第一个成功加载的位置。
引用@npm_support:
https://twitter.com/npm_support/status/968195526989512705
2/2 如果您想避免与依赖项相关的安装问题,一种方法是编写一个作为常规依赖项所需的包装器,并确保它具有
(并确保该包装器验证您拥有工作所需的一切)。optionalDeps
但恕我直言,它看起来更像是一种解决方法,而不是真正解决问题。
我可以理解 npm 希望保持可移植性并避免处理平台细节,但无论如何它都必须完成,而且恕我直言,在运行时这样做并不是最佳选择(如果想要优化代码大小,则需要特别注意)。
所以今天我没有最佳解决方案可以分享,但可以公开讨论提案。
npm 不能支持“条件依赖”吗?
我想到的第一件事是添加一个“覆盖”部分,它将更改(+添加、-删除、=替换)当前解析的部分。
例如:
dependencies: { "common-stuff": "*" }
overrides: {
"os: { linux: { dependencies: { "+best-linux-module" } } }
}
我认识的开发人员建议的其他选项是引入一个 provides 关键字,然后几个模块可以提供与解析器(la debian)所满足的语义相同的语义,但它会产生类似的开销。
我正在寻找一种通用方法,不仅关注操作系统支持,还关注其他风格的包(例如取决于引擎)。
您知道 NPM tracker 中的任何相关问题吗?如果不是,我正在考虑提交一个要跟踪的错误:
https://github.com/npm/npm/issues?q=dependency+conditional
欢迎对此想法提供反馈。