236

Let's say I have

"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\""
  },

What NPM command can I run to let all of these scripts launch sequentially. When I use pre/post fixing they launch sequentially but they don't wait for the parent script to finish before executing. I am assuming the only solution is like: How do I get Gulp tasks to fire sequentially when firing shell commands in an async.series helper function? ? I know this can be done with Gulp but I would like to stick with NPM for now to explore its capabilities. Thanks for any help!

Rice
  • 3,371
  • 4
  • 19
  • 23

9 Answers9

511

Invoke these scripts via npm run and chain them with double ampersand &&:

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

Explanation:

  • Use && (double ampersand) for sequential execution.
  • Use & (single ampersand) for parallel execution.
Mobiletainment
  • 22,201
  • 9
  • 82
  • 98
  • 8
    This works the best because it executes in order, being that each command doesn't execute until the previos is finished, as requested in the OP. Thanks – Rice Aug 29 '16 at 14:53
  • 56
    `&&` are evaluated by the shell and don't work on Windows. – Bernhard Döbler Mar 13 '18 at 19:25
  • Lets say that I have two scripts within my app. One launch a live server (script1), and another one a dyson server (script2). How I can create a script that triggers those two previous scripts? thanks :) – Alberto S. Mar 15 '18 at 23:11
  • @BernhardDöbler just add another npm command containing the above command - you don't have to run (and remember) this whole string from windows CLI. – Simon_Weaver May 09 '18 at 20:53
  • 11
    @RafeGoldberg The && operator has the same execution behavior in both windows and *nix environments, i.e. sequential execution..Unless there's something we're all missing? – Rice Jun 20 '18 at 18:56
  • 14
    @Rice oy vey; was being dumb and mixing up my single and double-ampersand operators. Per the `npm-run-all` docs: “we sometimes use `&` to run multiple command in parallel, but Windows' `cmd.exe`... does not support [this operator].” So it'd appear you were right — at least from my brief research the `&&` operator seems perfectly cross-platform compatible. – Rafe Goldberg Jun 26 '18 at 14:38
  • How can we chain ```npm i``` with something? I tried and it failed as it considers && as a package. – VPaul Jul 05 '19 at 13:54
  • @Rishinder just list all the packages you want to install separated by a **whitespace**: `npm i package1 package2 package3` – Mobiletainment Jul 05 '19 at 19:11
  • @Mobiletainment, that's not what I was trying to achieve. I wanted to execute other non installation scripts after ```npm i``` but it doesn't let me chain those. I've figured out a workaround but not very satisfied with it. – VPaul Jul 09 '19 at 15:47
  • @VPaul Shouldn't you perhaps use `postinstall` script for that? – Qwerty Oct 12 '20 at 10:30
  • I have read that the only difference between `&` and `&&` is that `&&` performs error checking and will not run commands to the right, if the commands on the left don't return expected result. [MS:KB Archive](https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/279253) – Qwerty Oct 12 '20 at 11:55
  • 3
    On Windows 10 the `&&` works for me. I have a ghost blog which my next js app connects to it. So, I use this command in my `package.json` file to run both the blog and the next js sequentially: `"scripts": { "all": "cd my-blog-folder && ghost start && cd.. && next dev", ... }`. Then I run this command to execute that: `npm run-script all` – Vahid Nov 15 '20 at 08:43
  • Coming here from an issue I face - "killall node && next dev" why doesn't this run sequentially? (> killall node && next dev....Terminated) – Cheetara Feb 16 '21 at 10:48
  • @Qwerty - This is for sure true on Windows, the single `&` may be context sensitive on unix and do other things . – dgo Feb 18 '21 at 18:23
  • 1
    as was mentioned && will not work in Windows shell ```&& are evaluated by the shell and don't work on Windows```, however it will work in git bash shell (automatically installed by git) or if you need it in regular cmd, than simple install of https://github.com/bmatzelle/gow utils will do the thing – bFunc Oct 23 '21 at 11:47
  • 1
    && works for me on windows shell. However single & does not. Concurrently or an inline node script is the correct way to run commands in parallel. – TamusJRoyce Nov 10 '21 at 20:54
  • Calling out to another script worked for me instead of `&` (ignore exit code) `"my-script": "npm run some-command-with-non-0-exit-code && do-something-else"` – Günter Zöchbauer Jan 11 '22 at 16:05
  • 1
    This answer frightens me. `&&` does run commands sequentially, if and only if the first command is successful (usually what you want). `&` does NOT run commands in parallel, though it may seem that way: The first command runs in the background, so its output might get lost and its success/failure certainly does. The entire process ends when the second command exits, meaning the first command might get killed off before it completes. @Or A's answer below is a viable option for sequential processing. `concurrently` is also a great option for running in parallel. – Brian Parks Sep 30 '22 at 21:24
55

Following @Mobiletainment's great answer, you can also use npm-run-all to make the command much shorter and much more readable. In your case:

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

run-s is a shortcut npm-run-all provides, that runs all the given npm-scripts sequentially, hence the -s (run-s is a shorter version of npm-run-all -s).

Or A.
  • 1,220
  • 1
  • 15
  • 28
  • 16
    While this seems like an elegant solution at first, checking out the dependency tree of `npm-run-all` reveals that it has 69 dependencies (not counting dev deps!), see e.g. https://npm.broofa.com/?q=npm-run-all . No thanks, I dont want to be a victim of some kind of sideload attack or a farce like the `left-pad` issue. – sydd Apr 06 '21 at 08:11
  • 1
    Do I see this correctly, that `run-s` is really just replacing `npm run pre-build && npm run build_logic && npm run post_build && npm run exit`? why would I introduce another dependency, that confuses every developer, who knows the `&&` command? In my case I am working on project that uses `run-s` (introduced by another dev) and it confuses me rather than helping me! Can I remove run-s securely or am I missing a difference here? – Merc Jun 02 '22 at 09:24
  • 1
    I think that, if you have a lot of scripts to run, and you are using Package.json as a Task Runner (like **Grunt** or **Gulp**) then **npm-run-all** may be a valid tool. However, if you want to run only two scripts like `build` and `clean` (for example) then I prefer to use the `&&` syntax. – Gil Epshtain Jun 20 '22 at 11:59
41

You can prefix your scripts pre and post so they will execute automatically:

"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\""
}

then run npm run build

Tzach Ovadia
  • 1,278
  • 9
  • 18
  • 4
    this doesn't work, as indicated in the question: "When I use pre/post fixing they launch sequentially but they don't wait for the parent script to finish before executing." – Russell Chisholm Sep 18 '19 at 20:56
23

You could just string them into another script. "start": "pre-build && build_logic && post_build && exit"

Dave V
  • 1,966
  • 9
  • 18
  • 3
    I would require them to wait for each other to finish, these will fire off sequentially but won't wait. – Rice Aug 26 '16 at 18:31
  • 3
    I don't think this is a node / npm problem. The `start` command you are executing in windows technically *is* finished. Use the `/wait` flag with `start` to force the `start` application to remain open until the internal method is also finished. – dvlsg Aug 26 '16 at 18:52
  • 1
    To test this -- run `start notepad` from a command prompt, then take a look at the original command prompt. You should be able to type in another command. Then run `start /wait notepad`. The `start` command should continue to "run" while your notepad window is open (take a look at the command prompt again). Then once you close notepad, `start` will be finished. – dvlsg Aug 26 '16 at 18:55
  • The \wait solution does not work for commands appended via double ampersand or pre/post fixed npm commands. – Rice Aug 26 '16 at 20:13
  • This doesn't work on windows. – Paul Dejean Jun 19 '23 at 17:47
7

You can use npm-run-all to combine multiple commands in a lot of different ways

For example, if you had the following scripts in your package.json:

"scripts": {
    "clean": "rimraf dist",
    "lint":  "eslint src",
    "build": "babel src -o lib"
}

You could run them all sequentially like this:

$ npm-run-all clean lint build

See this question for how to run multiple npm commands in parallel

KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • 1
    This is the way to go. npm-run-all is the best. And will produce a package.json that is cross-platform. – Robert May 14 '20 at 20:02
6

you can try:


"scripts": {
  "clean-dist": "rm -f ./dist/*.js && rm -f ./dist/*.map",
  "build": "npm run clean-dist && parcel build ./packages/index.html"
},
Muhammed Moussa
  • 4,589
  • 33
  • 27
4

There are several options that are better than the accepted answer:

  • && - runs commands sequentially, as long as each is successful: command && command && command; supported in most shells (early versions of Powershell did not support this) (thanks @Mobiletainment)
  • ; - runs commands sequentially, ignoring success/failure; supported in most, if not all, shells
  • the npm-run-all package - can run multiple commands either in sequence or in parallel; see the documentation for usage (thanks @Or A.)
  • the concurrently package - runs multiple commands in parallel (included because this is a popular Google result); see the documentation for usage
Brian Parks
  • 177
  • 8
2

Sequential & Parallel Mix Example

In case you need a mix, here's what I did to ensure command_1 runs and completes first, while command_2a and command_2b can run in parallel.

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

Practical Example:

    "dev": "yarn buildPackage && (yarn watchPackageSource & yarn watchExamplePage)"
Aerodynamic
  • 782
  • 5
  • 19
  • 3
    OS specific, doesn't work on windows – TamusJRoyce Nov 09 '21 at 06:23
  • 1
    That is not necessarily true and depends on your windows version and the shell that you use. Check the comments here (and maybe best use a unix shell): https://stackoverflow.com/a/39172660/5037146 – Aerodynamic Nov 09 '21 at 07:51
  • 1
    the point of npm is to be cross-shell/platform. otherwise you should stick with .sh, .bat, .makefile, cmake, sln, ... - Concurrently is an npm option. && is cross platform (seems to work even in powershell, even though running directly fails). & is not – TamusJRoyce Nov 09 '21 at 21:03
1

For all those who read this question in 2023, nowadays, Windows WSL allows you to run the Linux commands concatenation style '&' without installing additional dependencies.

We can bypass the command to WSL from PowerShell/cmd like that

wsl npm run build & npm start

It will depend slightly on what kind of instructions you want to run in such as .bat, .sh ...

enter image description here

Angel Fraga Parodi
  • 750
  • 10
  • 20