9

Как запустить несколько npm-скриптов параллельно?

14

В моем файле package.json определены два скрипта:

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

Каждый раз, когда я начинаю разработку в Node.js, мне нужно запускать эти два скрипта в параллельном режиме. Первоначально я думал добавить третий скрипт следующим образом:

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

Однако это приведёт к тому, что команда start-watch будет ожидать завершения, прежде чем начнётся выполнение wp-server.

Как я могу запустить эти скрипты в параллельном режиме? Имейте в виду, что я хочу видеть вывод этих команд. Если ваше решение включает инструмент сборки, то я предпочёл бы использовать gulp вместо grunt, так как я уже использую его в другом проекте.

5 ответ(ов)

0

Вам действительно не нужно использовать дополнительные модули для кросс-платформенных решений. Вы можете воспользоваться конструкцией command1 || command2, которая будет работать как в cmd.exe, так и в bash.

Вот пример вашего package.json, который иллюстрирует это решение:

"scripts": {
  "start-watch": "nodemon run-babel index.js",
  "wp-server": "webpack-dev-server",
  // первая команда предназначена для cmd.exe, вторая – для bash
  "dev": "(start npm run start-watch && start npm run wp-server) || (npm run start-watch & npm run wp-server)",
  "start": "npm run dev"
}

Таким образом, просто запустив npm start или npm run dev, вы сможете без проблем работать на всех платформах!

0

Если заменить двойной амперсанд на одинарный, скрипты будут выполняться параллельно.

0

Для начала, убедитесь, что у вас установлен пакет concurrently. Это можно сделать, выполнив команду:

npm install concurrently --save-dev

После этого вы можете использовать concurrently для одновременного запуска нескольких скриптов NPM. В вашем package.json у вас уже есть определенные скрипты:

"scripts": {
    "start:build": "tsc -w",
    "start:run": "nodemon build/index.js",
    "start": "concurrently npm:start:*"
  }

Здесь скрипт start запускает все скрипты, начинающиеся с start:. В вашем случае это start:build (который будет компилировать TypeScript в режиме "watch") и start:run (который будет запускать ваш скомпилированный файл с помощью nodemon).

Теперь, когда вы выполните команду:

npm start

Оба скрипта запустятся одновременно: один будет следить за изменениями в ваших TypeScript файлах и компилировать их по мере необходимости, а другой будет следить за вашими изменениями в скомпилированном JavaScript файле и перезапускать сервер, если вы внесете изменения.

Таким образом, concurrently помогает вам эффективно работать с несколькими процессами одновременно.

0

Быстрое решение

Если этот скрипт предназначен для частного модуля, который будет работать только на машинах с *nix-системами, вы можете использовать управляющий оператор для создания фоновых процессов, который выглядит следующим образом: &.

Вот пример, как это можно сделать в частичном файле package.json:

{
  "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 &"
  }
}

Затем вы можете выполнить оба скрипта параллельно, выполнив команду npm run serve-bundle. Вы также можете улучшить скрипты, чтобы выводить идентификаторы процессов (pid) вторичных процессов в файл следующим образом:

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

Ищите в Google что-то вроде bash control operator for forking, чтобы узнать больше о том, как это работает. Я также привел дополнительный контекст о том, как использовать техники Unix в проектах на Node ниже:

Дополнительный контекст о Unix-инструментах и Node.js

Если вы не на Windows, техники/инструменты Unix часто хорошо работают для решения задач с скриптами на Node, потому что:

  1. Многие аспекты Node.js тщательно имитируют принципы Unix.
  2. Вы на *nix (включая OS X), и NPM использует оболочку в любом случае.

Модули для системных задач в Nodeland тоже часто являются абстракциями или приближенными аналогами инструментов Unix, от fs до streams.

0

Мое решение похоже на решение Piittis, хотя у меня возникли некоторые проблемы с использованием Windows. Поэтому мне пришлось сделать проверку на win32.

const { spawn } = require("child_process");

function logData(data) {
    console.info(`stdout: ${data}`);
}

function runProcess(target) {
    let command = "npm";
    if (process.platform === "win32") {
        command = "npm.cmd"; // Я не шучу
    }
    const myProcess = spawn(command, ["run", target]); // npm run server

    myProcess.stdout.on("data", logData);
    myProcess.stderr.on("data", logData);
}

(() => {
    runProcess("server"); // скрипт из package json
    runProcess("client");
})();

Как видно, я добавил условие для определения платформы, чтобы правильно вызвать команду npm на Windows, используя npm.cmd. Это необходимо, так как на Windows обычная команда npm может не распознаваться.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь