【问题标题】:Npm: Run postinstall script only when installed as dependencyNpm:仅在作为依赖项安装时运行 postinstall 脚本
【发布时间】:2019-01-16 07:22:56
【问题描述】:

我开发了一个 npm 包(“node_commons”),它包含在我的其他项目中,如下所示:

package.json(其他项目)

"node-commons": "git+ssh://git@stash.custom.domain.net:7999/npm/libs/node_commons.git"

node_commons 包是用 ES6 编写的,但是这个版本以后不支持了,所以我用一个 postinstall 脚本用 babel 转译它。

package.json (node_commons)

"postinstall": "babel src -d src"

这很好用。当包作为依赖项包含在我的项目中时,文件将被转译。

我的问题:当我开发 node_commons 包时,我使用npm install 来安装内部依赖项。但后来我不想转换它。 我只想在包作为依赖项安装时进行转译(例如在我的其他项目中)。有没有办法做到这一点?

类似这样的:

package.json (node_commons)

"postinstall-as-dependency": "babel src -d src"

【问题讨论】:

  • 我也在想同样的事情。这是荒唐的。这两个场景应该有两个不同的生命周期钩子,因为它们是完全不同的任务。

标签: npm babeljs npm-scripts


【解决方案1】:

如果我理解正确,您希望您的包仅在用户将其安装为依赖项 (npm install node-common) 时运行 postinstall 脚本?

当您的安装后脚本运行时,它具有可用的 npm_config_save_dev,当用户使用 --save-dev 标志安装软件包时,这是“真”:

"postinstall": "! [ $npm_config_save_dev ] && echo \"Installed as a dependency\" || \"Installed as a dev dependency\""

【讨论】:

    【解决方案2】:
    • 在模块根目录中创建.no-postinstall 文件。
    • Mac 和 Linux: 将以下内容添加到 package.json"postinstall": "if [ ! -e .no-postinstall ]; then babel src -d src; fi"
    • Windows: 将以下内容添加到package.json"postinstall": if exist .no-postinstall () else (babel src -d src)"
    • 跨平台(更多工作): 您可以创建一个节点脚本(即./my-script.js)并使用fs 模块,检查.no-postinstall 的存在并使用child_process.exec() 执行babel src -d src,如official doc here 中所述。将您的脚本添加到package.json"postinstall": node my-script.js

    请注意,我使用的是 Mac,因此无法验证 Windows 版本。

    说明

    if [ ! -e .no-postinstall ] 检查给定文件的不存在(使用否定运算符!)。如果文件不存在,它将执行您的脚本。由于您将 .no-postinstall 文件添加到模块根目录,因此在安装内部模块时不会执行脚本。另一方面,将您的模块安装为依赖项的模块在其根目录中没有 .no-postinstall 文件,您的脚本将被执行。

    .no-postinstall 不是特殊名称,您可以使用任何您选择的名称。

    【讨论】:

    【解决方案3】:

    就我而言,我有一个安装后脚本,我只想在包没有作为依赖项安装时运行它。

    这是我使用的package.json 脚本:

    {
        [...]
        "scripts": {
            "@comment_postinstall": "Behavior of the node-js subscript below: if '.git' doesn't exist under my-lib, it's installed as a dep, so do nothing -- else, return error-code 1, causing patch-package to run.",
            "postinstall": "node -e \"let myLibAsDep = !require('fs').existsSync('.git'); if (!myLibAsDep) process.exit(1);\" || patch-package"
        },
        [...]
    }
    

    如果您希望脚本仅在作为依赖项安装时运行,您当然可以反转 if (!myLibAsDep)

    【讨论】:

      【解决方案4】:

      我有同样的问题,我有一个安装后脚本,我只想在包作为依赖项安装时运行它。

      我在安装后脚本的顶部添加了:

      if (!process.cwd().includes('node_modules')) {
       return;
      }
      

      然后它只在模块存在于node_modules 目录下时运行。

      【讨论】:

      • 在大多数情况下都可以工作,但我认为某些情况下会失败。 (例如,如果在父项目和您的 lib 下存在依赖项,并且版本不兼容,那么您的 lib 将拥有自己的 node_modules 文件夹,即使您的 lib 作为依赖项安装也是如此) ,您可以修改 if 语句以检查您知道父项目永远不会拥有的 lib 的特定依赖项,因此只有当您的 lib 未作为依赖项安装时,它才会在您的 lib 下。
      • 我找到了一个更好的方法:只需检查您的 lib 目录中是否存在 .git 文件夹。如果它不存在,则意味着您的 lib 已作为依赖项安装(好吧,假设您在开发库时使用 git ——这几乎是我认为的每个人)。完整解决方案:stackoverflow.com/a/68915638/2441655
      猜你喜欢
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2020-12-28
      • 2021-11-22
      • 2018-08-05
      • 1970-01-01
      • 2015-09-18
      • 2016-03-14
      相关资源
      最近更新 更多