ChatGPT解决这个技术问题 Extra ChatGPT

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!

Updated answer at the bottom
According the documentation of Start command, you should be able to use /wait parameter (Start application and wait for it to terminate)

M
Mobiletainment

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.


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
&& are evaluated by the shell and don't work on Windows.
This should not be the accepted answer. Per @BernhardDöbler, the && syntax is a UNIX construct. It will behave incorrectly on Window's machines, with potentially breaking consequences for your build process.
@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 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.
O
Or A.

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


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. 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.
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?
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.
T
Tzach Ovadia

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


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."
D
Dave V

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


I would require them to wait for each other to finish, these will fire off sequentially but won't wait.
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.
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.
The \wait solution does not work for commands appended via double ampersand or pre/post fixed npm commands.
K
KyleMit

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


This is the way to go. npm-run-all is the best. And will produce a package.json that is cross-platform.
M
Muhammed Moussa

you can try:


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

A
Aerodynamic

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

OS specific, doesn't work on windows
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): stackoverflow.com/a/39172660/5037146
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