NPM – 有条件地增加全球path

在Node package.json文件中,可以将多个可执行文件映射到全局NPM安装( npm install -g )上的PATH环境variables:

 "bin": { "foo": "./bin/foo.js", "bar": "./bin/bar.js" }, 

我有一个独特的项目,需要映射操作系统上没有它的现有PATHvariables。 例如,我想添加一个名为grep的命令给PATH当且仅当它被安装在Windows计算机上。 如果计算机正在运行其他操作系统,则NPM安装将显然失败。


有没有什么办法可以预先确定在安装中可用的bin选项?


哦,快点 – 我只是有一个主意!

这将工作:

  1. 父模块具有npm (编程版本)作为依赖。
  2. 在全局安装中,运行父模块的package.json中声明的安装后脚本。
  3. 安装后脚本对系统进行检查以查看存在哪些命令。 这将比“Windows或不Windows”更成熟 – 它会试图执行一个命令列表,看看哪些失败。
  4. 对于每个不存在的命令,安装后的脚本以编程方式在所有子模块上运行npm install -g (每个命令一个,如grep )。

这将需要一段时间, npm模块是巨大的,但它似乎是可行的。 没有?

似乎没有办法通过package.json直接做到这一点,但是可能(也是可取的)做如下的事情:

  • 为每个要注册的可执行文件创build一个单独的npm模块(例如my-win-grep )。
  • my-win-grep模块中,实现要运行的可执行代码,并在该模块中注册PATH /可执行文件的值。
  • package.json -greppackage.json中,包含一个将其限制为在Windows上安装的os字段。
  • 在您的原始模块中,将my-win-grep列为optionalDependency

这样,如果有人在Windows上安装了你的原始模块,它会安装my-win-grep ,它将注册一个可执行文件在grep命令下运行。

对于其他系统上的用户, my-win-grep模块由于os要求而不能安装,但是主模块会继续安装,因为它忽略了OptionalDependencies下的失败。 所以原始的grep可执行文件将保持不变。

更新的问题

这种方法听起来像是应该起作用 – 就像你说的那样,npm依赖是相当大的,但是它确实避免了执行额外的符号链接,并且仍然具有上述的在独立模块中具有每个OS特定function的优点。

唯一需要注意的是,可能在程序化npm文档中:

目前,您不能单独为任何npm函数设置configuration。 由于npm是一个单例,任何对npm.config.set的调用都会改变该进程中所有npm命令的值

所以这可能意味着你不能在你的安装中指定-g ,而是必须在第一次安装之前全局设置它。 这不应该是一个问题,但你可能需要testing一下,找出确切的。

最后…

你也许还想看一下https://github.com/lastboy/package-script – 即使你不使用它,它可能会给你一些灵感来实现。