微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当`npm install`被赋予`-g`标志时如何安装额外的bin文件?

如何解决当`npm install`被赋予`-g`标志时如何安装额外的bin文件?

有什么方法可以在通过 npm install 运行时仅安装部分 NodeJS 项目,而在使用 npm install -g 时安装其他功能吗?

我有一个带有命令行界面的库,但是 CLI 对使用我的库的任何下游项目都没有用。因此,当这些项目拉入我的库时,我不希望它们拉下 chalk 之类的依赖项,这些依赖项仅用于他们永远不会触及的 CLI。

但是,如果最终用户决定使用 npm install -g 在他们的系统上全局安装我的库,那么我希望安装 CLI,并通过 bin 中的 package.json 部分放置在他们的路径中这样他们就可以像运行任何其他程序一样运行它。

如果不将 CLI 拆分为单独的包,我无法弄清楚如何执行此操作。我调查的选项是:

  • 将 CLI 依赖项设为 devDependencies。这可以防止在下游项目中安装 chalk 等,但这里的缺点是用户必须 npm install -g 处于开发模式,这意味着他们也安装了测试框架和 linting 工具,即使他们永远不会使用它们。
  • 将 CLI 作为单独的 NodeJS 包/模块。这里的缺点是它使测试变得困难(因为 CLI 和库经常同时被修改并用于测试新功能),并且想要为库做出贡献的开发人员将不得不将这两个包链接起来,所以尽管它会起作用,但从工作流程的角度来看并不理想。
  • 将 CLI 放在主包内的文件夹中,并在其中为 CLI 创建另一个 package.json,通过 npm install .. 拉入主项目。这一直有效,直到您到达安装点,当您意识到发布包后无法安装 CLI 时。 npm install @my/library 只会从项目根目录中的 package.json 安装,没有办法说“哦也将包安装在 cli 子目录中。”

理想情况下,我想要的是:

  • npm install @my/library - 由希望在其项目中使用该库的开发人员运行。仅将库添加到其项目的依赖项中,忽略 CLI 和 CLI 需要的任何依赖项。
  • npm install -g @my/library - 由最终用户运行,在他们的系统上全局安装库和 CLI,包括 CLI 依赖项,并通过 package.json bin 将 CLI 添加用户的路径部分。
  • npm install --dev - 供库的开发人员用于安装测试框架,以便他们可以在提交代码以供包含之前运行单元测试。
  • 不必将 CLI 拆分为单独的项目。

这可能吗?

解决方法

有什么方法可以在通过 npm install 运行时仅安装部分 NodeJS 项目,而在使用 npm install -g 时安装其他功能吗?

您可以编写一个使用 postinstall script(或其他类似包)的 is-globally-installed 来检查模块是否已全局安装,然后运行任何适合安装 CLI 的程序(可能是 {{1} } 对于只有 CLI 的单独包)。

,

好吧,我想出了一个解决方法。

我将 CLI 重新设置为仅用于开发(其要求在 devDependencies 中,因此本地开发人员可以使用它,但他们不会使用该库进入下游项目)。然后我为 CLI 创建了另一个包,但它只是一个 package.json 文件,没有别的。

这个包的作用是依赖于主库,加上 CLI 需要的依赖。然后它使用 bin 部分指向主库中的 CLI,所以这个包中不需要任何代码 - 它实际上只是一个文件。像这样:

{
  "name": "@my/library-cli",// new module to install the CLI
  "bin": {
    "myprog": "./node_modules/@my/library/bin/myprog.js"  // the command is inside the dependency
  },"dependencies": {
    "@my/library": "*",// require the library itself where the CLI code sits
    "command-line-args": "*"  // dependency needed by the CLI
  }
}

唯一的缺点是这个新包的 dependencies 需要与主库的 devDependencies 保持同步(至少是 CLI 要求的 deps)但因为它们不会改变通常在我的情况下,我可以忍受。

我确实按照@Trott 的建议尝试了 postinstall 钩子,但似乎没有用:

"scripts": {
  "postinstall": "[ $npm_config_global == 'true' ] && (cd cli && npm install -g)"
}

出于某种原因,它非常慢,似乎陷入了循环,一遍又一遍地尝试安装却失败了。我也不确定它是否会尊重通过 npm install -g --prefix /my/install/folder 之类的命令启动,因为该非标准前缀可能不会传递给子 npm 进程。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。