按顺序运行NPM脚本

241

假设我拥有

"scripts": {
    "pre-build": "echo \"Welcome\" && exit 1",
    "build_logic": "start cmd.exe @cmd /k \"yo esri-appbuilder-js:widget && exit 1\"",
    "post_build":  "start C:\\WebAppBuilderForArcGIS\\startupShortcut",
    "exit" : "start cmd.exe @cmd /k \"echo \"goodbye\" && exit 1\""
  },

我想知道用哪个NPM命令可以让这些脚本按顺序启动。当我使用pre/post修饰时,它们是按顺序启动的,但在执行之前它们不会等待父脚本完成。我猜唯一的解决方案就像这里所述:如何在async.series帮助函数中触发shell命令时按顺序触发Gulp任务? 我知道可以使用Gulp来完成,但现在我想继续探索NPM的功能。感谢任何帮助!


请提供需要翻译的英文内容。 - Tzach Ovadia
根据Start命令的文档,您应该能够使用/wait参数(启动应用程序并等待其终止)。 - Tzach Ovadia
9个回答

520

通过npm run调用这些脚本,并使用双“&&”链接它们:

npm run pre-build && npm run build_logic && npm run post_build && npm run exit

说明:

  • 使用&&(双和符号)进行顺序执行。
  • 使用&(单和符号)进行并行执行。

8
这种方法最好,因为它按顺序执行,也就是说每个命令只有在前一个命令完成后才会执行,正如OP所要求的一样。谢谢。 - Rice
59
&& 在 shell 中进行求值,在 Windows 上不起作用。 - Bernhard Döbler
11
@RafeGoldberg,“&&”运算符在Windows和*nix环境下具有相同的执行行为,即顺序执行。除非我们都有什么遗漏? - Rice
14
噢,我真笨,混淆了单个和双个“&”运算符。根据npm-run-all文档:“有时我们使用“&”来并行运行多个命令,但是Windows的cmd.exe不支持[此运算符]。”所以看起来你是对的 - 至少从我的简要调查来看,“&&”运算符似乎在跨平台方面完全兼容。 - Rafe Goldberg
4
在Windows 10上,&& 对我有效。我有一个Ghost博客,我的Next.js应用程序连接到它。因此,我在我的package.json文件中使用此命令依次运行博客和Next.js: "scripts": { "all": "cd my-blog-folder && ghost start && cd.. && next dev", ... }。然后我运行此命令来执行:npm run-script all - Vahid
显示剩余13条评论

56

根据@Mobiletainment的出色答案,你也可以使用npm-run-all来使命令更短、更易读。在你的情况下:

"scripts": {
    ...
    "build": "run-s pre-build build_logic post_build exit"
}

run-snpm-run-all提供的快捷方式,按顺序运行所有给定的npm脚本,因此有-srun-snpm-run-all -s的简短版本)。


17
虽然这一开始看起来似乎是一个优雅的解决方案,但检查npm-run-all的依赖树后发现它有69个依赖(不包括开发依赖!),例如请参见 https://npm.broofa.com/?q=npm-run-all。谢绝了,我不想成为某种侧载攻击或类似“left-pad”问题的受害者。 - sydd
1
我是否理解正确,run-s 实际上只是替换了 npm run pre-build && npm run build_logic && npm run post_build && npm run exit?为什么要引入另一个依赖项,这会让每个知道 && 命令的开发人员感到困惑呢?在我的情况下,我正在处理使用 run-s 的项目(由另一个开发人员引入),它让我感到困惑而不是帮助我!我能安全地删除 run-s 吗,还是我错过了什么区别? - Merc
1
我认为,如果你有很多脚本要运行,并且正在使用Package.json作为任务运行器(如Grunt或Gulp),那么npm-run-all可能是一个有效的工具。但是,如果你只想运行两个脚本,比如buildclean,那么我更喜欢使用&&语法。 - Gil Epshtain

44

您可以在脚本前缀中添加 prepost,以便自动执行:

"scripts": {
  "prebuild": "echo \"Welcome\" && exit 1",
  "build": "start cmd.exe @cmd /k \"yo esri-appbuilder-js:widget && exit 1\"",
  "postbuild":  "start C:\\WebAppBuilderForArcGIS\\startupShortcut",
  "exit" : "start cmd.exe @cmd /k \"echo \"goodbye\" && exit 1\""
}

然后运行 npm run build



5
根据问题所述:“当我使用前/后缀时,它们按顺序启动,但在执行之前不等待父脚本完成”,因此这种方法行不通。 - Russell Chisholm

24

你可以将它们拼接到另一个脚本中。"start": "pre-build && build_logic && post_build && exit"


3
我会要求他们等待彼此完成,这些动作将按顺序依次触发但不会等待。 - Rice
3
我认为这不是一个 Node/npm 的问题。你在 Windows 上执行的 start 命令在技术上已经完成了。请使用 /wait 标记和 start 命令一起,强制使 start 应用程序保持打开状态,直到内部方法也完成。 - dvlsg
1
要测试这个功能,可以从命令提示符中运行“start notepad”命令,然后查看原始命令提示符。您应该能够输入另一个命令。然后运行“start /wait notepad”。当您的记事本窗口打开时,“start”命令应该继续“运行”(再次查看命令提示符)。然后一旦您关闭记事本,“start”就会完成。 - dvlsg
\Wait 方案对于通过双和符号附加的命令或前/后固定的 npm 命令不起作用。 - Rice
这在Windows上不起作用。 - Paul Dejean

7
你可以使用 npm-run-all 来以多种不同的方式组合多个命令。
例如,如果你在你的 package.json 文件中有以下脚本:
"scripts": {
    "clean": "rimraf dist",
    "lint":  "eslint src",
    "build": "babel src -o lib"
}

你可以按照如下方式依次运行它们:
$ npm-run-all clean lint build

请参考如何并行运行多个npm命令的问题


1
这是正确的方式。npm-run-all 是最好的选择。并且将生成一个跨平台的 package.json 文件。 - Robert

6

你可以尝试:


"scripts": {
  "clean-dist": "rm -f ./dist/*.js && rm -f ./dist/*.map",
  "build": "npm run clean-dist && parcel build ./packages/index.html"
},

5

以下选项比接受的答案更好:

  • && - 顺序运行命令,只要每个命令成功: command && command && command; 在大多数 shell 中支持(早期版本的 Powershell 不支持此选项)(感谢 @Mobiletainment)
  • ; - 依次运行命令,忽略成功/失败;在大多数 shell 中支持,如果不是所有的话
  • npm-run-all 包 - 可以按照顺序或并行运行多个命令;有关使用,请参见文档(感谢 @Or A.)
  • concurrently 包 - 并行运行多个命令(包含在此处是因为它是一个流行的 Google 搜索结果);有关使用,请参阅文档

2

顺序和并行混合示例

如果您需要混合使用,以下是我所做的,以确保command_1先运行并完成,而command_2a和command_2b可以并行运行。

    "dev": "yarn command_1 && (yarn command_2a & yarn command_2b)"

实际例子:
    "dev": "yarn buildPackage && (yarn watchPackageSource & yarn watchExamplePage)"

3
特定于操作系统,无法在Windows上运行。 - TamusJRoyce
1
这并不一定正确,取决于您的Windows版本和所使用的shell。在此处检查评论(最好使用Unix shell):https://dev59.com/B1kT5IYBdhLWcg3wB7Is#39172660 - Aerodynamic
1
npm 的重点在于跨平台/跨 shell。否则,您应该坚持使用 .sh、.bat、.makefile、cmake、sln 等等。Concurrently 是 npm 的一个选项。&& 是跨平台的(即使在 PowerShell 中似乎也可以工作,尽管直接运行会失败)。& 不是。 - TamusJRoyce

2

对于所有在2023年阅读此问题的人,现在,Windows WSL允许您运行Linux命令串联样式'&'而无需安装其他依赖项。

我们可以像这样从PowerShell/cmd绕过命令到WSL

wsl npm run build & npm start

这将略微取决于您想要运行的指令类型,例如.bat、.sh等。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接