Rice
Rice

Reputation: 3531

Running NPM scripts sequentially

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!

Upvotes: 251

Views: 220760

Answers (10)

Mobiletainment
Mobiletainment

Reputation: 23311

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

You can either run the above command directly on the command line, or you can set it as another script like this:

"scripts": {
    ...
    "build": "npm run pre-build && npm run build_logic && npm run post_build && npm run exit",
}

And then run the whole list via npm run build.

Explanation:

  • Use && (double ampersand) for sequential execution.
    (Some early versions of Windows Powershell did not support this syntax, but recent versions should.)
  • Use & (single ampersand) for parallel execution. Test carefully as commands earlier in the list may be run in background and you may potentially lose the output including any error messages (depending on your platform/shell).

Upvotes: 539

Stanley Ulili
Stanley Ulili

Reputation: 1424

Update as of 2024

Node.js 22 or higher ships with a faster and native option. You can use node --run in place of npm run.

So Mobiletainment answer can be rewritten like this:

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

Note: At the time of writing, the feature is experimental.

Upvotes: 1

Angel Fraga Parodi
Angel Fraga Parodi

Reputation: 790

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

Upvotes: 2

Brian Parks
Brian Parks

Reputation: 197

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

Upvotes: 6

Aerodynamic
Aerodynamic

Reputation: 819

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)"

Upvotes: 2

Muhammed Moussa
Muhammed Moussa

Reputation: 5205

you can try:


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

Upvotes: 6

KyleMit
KyleMit

Reputation: 30267

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

Upvotes: 8

Tzach Ovadia
Tzach Ovadia

Reputation: 1316

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

Upvotes: 44

Or A.
Or A.

Reputation: 1276

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).

Upvotes: 58

Dave V
Dave V

Reputation: 1976

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

Upvotes: 24

Related Questions