How can I run multiple npm scripts in parallel?

后端 未结 22 2112
灰色年华
灰色年华 2020-11-22 05:48

In my package.json I have these two scripts:

  \"scripts\": {
    \"start-watch\": \"nodemon run-babel index.js\",
    \"wp-server\": \"webpack-         


        
相关标签:
22条回答
  • 2020-11-22 06:20
    npm-run-all --parallel task1 task2
    

    edit:

    You need to have npm-run-all installed beforehand. Also check this page for other usage scenarios.

    0 讨论(0)
  • 2020-11-22 06:20

    ... but that will wait for start-watch to finish before running wp-server.

    For that to work, you will have to use start on your command. Others have already illustrated but this is how it will work, your code below:

    "dev": "npm run start-watch && npm run wp-server"

    Should be :

    "dev": " start npm run start-watch && start npm run wp-server"

    What this will do is, it will open a separate instance for each command and process them concurrently, which shouldn't be an issue as far as your initial issue is concerned. Why do I say so? It's because these instances both open automatically while you run only 1 statement, which is your initial goal.

    0 讨论(0)
  • 2020-11-22 06:22

    How about forking

    Another option to run multiple Node scripts is with a single Node script, which can fork many others. Forking is supported natively in Node, so it adds no dependencies and is cross-platform.


    Minimal example

    This would just run the scripts as-is and assume they're located in the parent script's directory.

    // fork-minimal.js - run with: node fork-minimal.js
    
    const childProcess = require('child_process');
    
    let scripts = ['some-script.js', 'some-other-script.js'];
    scripts.forEach(script => childProcess.fork(script));
    

    Verbose example

    This would run the scripts with arguments and configured by the many available options.

    // fork-verbose.js - run with: node fork-verbose.js
    
    const childProcess = require('child_process');
    
    let scripts = [
        {
            path: 'some-script.js',
            args: ['-some_arg', '/some_other_arg'],
            options: {cwd: './', env: {NODE_ENV: 'development'}}
        },    
        {
            path: 'some-other-script.js',
            args: ['-another_arg', '/yet_other_arg'],
            options: {cwd: '/some/where/else', env: {NODE_ENV: 'development'}}
        }
    ];
    
    let runningScripts= [];
    
    scripts.forEach(script => {
        let runningScript = childProcess.fork(script.path, script.args, script.options);
    
       // Optionally attach event listeners to the script
       runningScript.on('close', () => console.log('Time to die...'))
    
        runningScripts.push(runningScript); // Keep a reference to the script for later use
    });
    

    Communicating with forked scripts

    Forking also has the added benefit that the parent script can receive events from the forked child processes as well as send back. A common example is for the parent script to kill its forked children.

     runningScripts.forEach(runningScript => runningScript.kill());
    

    For more available events and methods see the ChildProcess documentation

    0 讨论(0)
  • 2020-11-22 06:24

    Simple node script to get you going without too much hassle. Using readline to combine outputs so the lines don't get mangled.

    const { spawn } = require('child_process');
    const readline = require('readline');
    
    [
      spawn('npm', ['run', 'start-watch']),
      spawn('npm', ['run', 'wp-server'])
    ].forEach(child => {
        readline.createInterface({
            input: child.stdout
        }).on('line', console.log);
    
        readline.createInterface({
            input: child.stderr,
        }).on('line', console.log);
    });
    
    0 讨论(0)
  • 2020-11-22 06:26

    If you replace the double ampersand with a single ampersand, the scripts will run concurrently.

    0 讨论(0)
  • 2020-11-22 06:26

    Quick Solution

    In this case, I'd say the best bet If this script is for a private module intended to run only on *nix-based machines, you can use the control operator for forking processes, which looks like this: &

    An example of doing this in a partial package.json file:

    {
      "name": "npm-scripts-forking-example",
      "scripts": {
        "bundle": "watchify -vd -p browserify-hmr index.js -o bundle.js",
        "serve":  "http-server -c 1 -a localhost",
        "serve-bundle": "npm run bundle & npm run serve &"
      }
    

    You'd then execute them both in parallel via npm run serve-bundle. You can enhance the scripts to output the pids of the forked process to a file like so:

    "serve-bundle": "npm run bundle & echo \"$!\" > build/bundle.pid && npm run serve & echo \"$!\" > build/serve.pid && npm run open-browser",
    

    Google something like bash control operator for forking to learn more on how it works. I've also provided some further context regarding leveraging Unix techniques in Node projects below:

    Further Context RE: Unix Tools & Node.js

    If you're not on Windows, Unix tools/techniques often work well to achieve something with Node scripts because:

    1. Much of Node.js lovingly imitates Unix principles
    2. You're on *nix (incl. OS X) and NPM is using a shell anyway

    Modules for system tasks in Nodeland are also often abstractions or approximations of Unix tools, from fs to streams.

    0 讨论(0)
提交回复
热议问题