多个脚本上的 npm 脚本挂钩

M Z*_*tra 6 hook npm package.json angular

我有一个关于脚本前钩子的相当简单的问题。

在我的 package.json 中,我有几个命令都应该运行相同的前脚本。我已经有办法做到这一点,但我想知道是否有更有效的原因这样做。

当前实施

{
    "scripts": {
        "myproject:run": "npm run custom.prescript && ng serve ...",
        "myproject:prod": "npm run custom.prescript && ng serve -env=prod ...",
        "myproject:build.devserver": "npm run custom.prescript && ng build -env=dev ...",
        ...
        "myproject:build.prodserver": "npm run custom.prescript && ng build -env=prod ...",
        "custom.prescript": "..."
    }
}
Run Code Online (Sandbox Code Playgroud)

这一切正常,但我希望有一种更清洁的方法来实现这一点。因为我有大约 20 个这些脚本需要相同的前脚本。当我由于某种原因必须更改命令时,我必须为 repo 中的每个项目(大约 5 个项目)执行 20 次更改。

我知道有一种方法可以通过创建一个具有相同名称和前缀“pre”的脚本来添加预脚本,以确保它在该特定脚本之前运行,但据我所知,这不适用于多个脚本。

我的目标示例

{
    "scripts": {
        "myproject:run": "ng serve ...",
        "myproject:prod": "ng serve -env=prod ...",
        ...
        "secondproject:run": "ng serve ...",
        "secondproject:prod": "ng serve -env=prod ...",
        ...
        "premyproject:*": "...",  // Runs before all 'myproject:*' scripts
        "presecondproject:*": "..."  // Runs before all 'secondproject:*' scripts
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更有效的方法来实现这一点,还是我必须像我已经在做的那样做?

谢谢你的时间!:)

Rya*_*ale 1

我想扩展上面@pqnet 的评论:

package.json 脚本并不适合做复杂的事情......

如果需要的话,请多读几遍这句话。像 grunt 和 gulp 这样的工具很好,但我发现它们给本应相当简单的过程增加了很多不必要的复杂性。你现在所做的还不错,因为很清楚正在发生什么。我完全理解你的心情:

当我由于某种原因必须更改命令时,我必须为存储库中的每个项目(大约 5 个项目)执行 20 次。

然而,更新一堆脚本可能是一个简单的查找/替换,一年只发生几次。一般来说,我可以非常肯定地说,您不想在 npm 脚本的运行方式中引入任何“魔法”。即使是内置的前/后挂钩也不是一个好主意,原因如下:

  • 当您的脚本调用其他脚本而其他脚本调用其他脚本并且其中一些脚本具有前/后挂钩时,它会造成很多混乱 - 很难看到正在发生的事情的全貌,并且您花费大量时间试图弄清楚事情的正确顺序。一旦你把这一切都弄清楚了,当你出城时,你团队中的另一个人就会把它搞砸,没有人能弄清楚如何解决它(这以前发生在我身上......它很糟糕)。
  • 有时您不希望钩子运行...您该怎么办?更多 CLI 选项?呃,不,谢谢!
  • 有些单词实际上以字母“pre”或“post”开头...当您有“prepoulate”或“postfix”等脚本时,事情会变得非常混乱...然后有人定义了一个名为“populate”的脚本”或“修复”,却没有意识到他们正在激活一些不需要的“魔法”(这之前也发生在我身上 - 很糟糕)。
  • 还有其他原因可以避免“魔法”......我建议你用谷歌搜索一下。我几年前就停止使用前/后钩子,并且从未后悔过。

几乎在我开发过的每个应用程序中,我最终都需要运行大量与您正在执行的操作类似的脚本......尤其是当我开始使用 monorepos 并管理具有复杂构建的复杂项目时。在这种情况下,我创建实际的 JS/TS 文件并使用代码管理复杂性 - 它更容易阅读,并且更容易组成复杂的管道。我知道这不是你想听到的……我确信我会得到一些反对票,但我强烈建议你不要陷入钩子陷阱。

如果您决定采纳我的建议,我会定期使用一些工具来让我的生活更轻松:

  • tsx - 在 TS 中编写脚本并使用npx tsx <path_to_file>.
  • zx - 从 JS/TS 执行 bash 命令
  • Commander - 将您的脚本变成带有选项和子命令的受人尊敬的 CLI 工具
  • 提示- 通过提示用户提供附加信息来增强您的 CLI

希望有帮助。