Подтвердить что ты не робот

Как я могу запускать несколько сценариев npm параллельно?

В моем package.json у меня есть два сценария:

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

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

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

... но это будет ждать завершения start-watch до запуска wp-server.

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

4b9b3361

Ответ 1

Используйте пакет под названием concurrently.

npm i concurrently --save-dev

Затем настройте задачу npm run dev так:

"dev": "concurrently --kill-others \"npm run start-watch\" \"npm run wp-server\""

Ответ 2

Использование пакета Concurrently работает, но вам это не нужно. Вы можете просто использовать конвейер на машинах под управлением UNIX для выполнения параллельных задач. Я бы предложил этот метод поверх другого, потому что он избавляет вас от необходимости добавлять дополнительную зависимость.

"dev": "npm run start-watch > /dev/null | npm run wp-server"

примечание: первая команда будет игнорировать вывод

Ответ 3

Если вы используете UNIX-подобную среду, просто используйте & в качестве разделителя:

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

В противном случае, если вы заинтересованы в кросс-платформенном решении, вы можете использовать npm-run-all модуль:

"dev": "npm-run-all --parallel start-watch wp-server"

Ответ 4

Из окон cmd вы можете использовать start:

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

Каждая запущенная таким образом команда запускается в своем собственном окне.

Ответ 5

Вы должны использовать npm -r un-all (или concurrently parallelshell), потому что он имеет больший контроль над командами запуска и уничтожения. Операторы &, | плохие идеи, потому что вам нужно будет остановить их вручную после завершения всех тестов.

Это пример тестирования транспортира через npm:

scripts: {
  "webdriver-start": "./node_modules/protractor/bin/webdriver-manager update && ./node_modules/protractor/bin/webdriver-manager start",
  "protractor": "./node_modules/protractor/bin/protractor ./tests/protractor.conf.js",
  "http-server": "./node_modules/http-server/bin/http-server -a localhost -p 8000",
  "test": "npm-run-all -p -r webdriver-start http-server protractor"
}

-p= -p команды параллельно.

-r= Убить все команды, когда одна из них завершается с кодом выхода, равным нулю.

Запуск npm run test запустит драйвер Selenium, запустит http-сервер (для обслуживания ваших файлов) и запустит тесты транспортира. После завершения всех тестов он закроет http-сервер и драйвер селена.

Ответ 6

Лучшим решением является использование &

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

Ответ 7

Вы можете использовать один & для сценария параллельного запуска

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

Ссылка

Ответ 8

У меня есть кроссплатформенное решение без каких-либо дополнительных модулей. Я искал что-то вроде блока try catch, который мог бы использовать как в cmd.exe, так и в bash.

Решение это command1 || command2 command1 || command2 который, кажется, работает в обеих средах одинаково. Таким образом, решение для ОП:

"scripts": {
  "start-watch": "nodemon run-babel index.js",
  "wp-server": "webpack-dev-server",
  // first command is for the cmd.exe, second one is for the 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 startnpm run dev) будут работать на всех платформах!

Ответ 9

Я проверил почти все решения сверху и только с помощью npm -r - не все я смог решить все проблемы. Основным преимуществом перед всеми другими решениями является возможность запуска скрипта с аргументами.

{
  "test:static-server": "cross-env NODE_ENV=test node server/testsServer.js",
  "test:jest": "cross-env NODE_ENV=test jest",
  "test": "run-p test:static-server \"test:jest -- {*}\" --",
  "test:coverage": "npm run test -- --coverage",
  "test:watch": "npm run test -- --watchAll",
}

Примечание run-p является ярлыком для npm-run-all --paraller

Это позволяет мне запускать команды с такими аргументами, как npm run test:watch -- Something.

РЕДАКТИРОВАТЬ:

Для npm-run-all есть еще одна полезная опция:

 -r, --race   - - - - - - - Set the flag to kill all tasks when a task
                            finished with zero. This option is valid only
                            with 'parallel' option.

Добавьте -r к своему npm-run-all для npm-run-all чтобы завершить все процессы, когда один из них завершится с кодом 0. Это особенно полезно, когда вы запускаете HTTP-сервер и другой скрипт, который использует сервер.

  "test": "run-p -r test:static-server \"test:jest -- {*}\" --",

Ответ 10

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

Ответ 11

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

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

Пример этого в частичном файле 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. Вы можете улучшить скрипты для вывода pids разветвленного процесса в файл следующим образом:

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

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

Дальнейший контекст RE: Unix Tools и Node.js

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

  • Большая часть Node.js с любовью имитирует принципы Unix.
  • Вы находитесь на * nix (включая OS X), а NPM использует оболочку в любом случае

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

Ответ 12

npm-run-all --parallel task1 task2

редактировать:

Вам необходимо предварительно установить npm-run-all. Также проверьте эту страницу для других сценариев использования.

Ответ 13

Я столкнулся с проблемами с & и |, которые выходят из состояния и бросают ошибку соответственно.

Другие решения хотят запускать любую задачу с заданным именем, например, npm-run-all, что не было моим прецедентом.

Итак, я создал npm-run-parallel, который запускает npm-скрипты асинхронно и отчитывается, когда они будут сделаны.

Итак, для ваших скриптов это будет:

npm-run-parallel wp-server start-watch

Ответ 14

Как насчет разветвления

Другой вариант запуска нескольких сценариев Node - с одним сценарием Node, который может разветвлять многие другие. Форкинг изначально поддерживается в Node, поэтому он не добавляет никаких зависимостей и является кроссплатформенным.


Минимальный пример

Это просто запустит сценарии как есть и предположит, что они находятся в родительском каталоге сценариев.

// 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));

Подробный пример

Это будет запускать сценарии с аргументами и настраиваться многими доступными параметрами.

// 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 processes = [];

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
});

Общение с помощью разветвленных скриптов

Forking также имеет дополнительное преимущество, заключающееся в том, что родительский скрипт может получать события от разветвленных дочерних процессов, а также отправлять их обратно. Типичным примером является родительский скрипт для уничтожения его разветвленных потомков.

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

Для более доступных событий и методов смотрите документацию ChildProcess

Ответ 15

В моем случае у меня есть два проекта, один из которых был UI, а другой - API, и оба имеют свой собственный скрипт в соответствующих файлах package.json.

Итак, вот что я сделал.

npm run --prefix react start&  npm run --prefix express start&

Ответ 16

Я использовал npm-run-all в течение некоторого времени, но я никогда не ладил с ним, потому что вывод команды в режиме просмотра не очень хорошо работает вместе. Например, если я запущу create-react-app и jest в режиме просмотра, я смогу видеть вывод только из последней команды, которую я выполнил. Поэтому большую часть времени я выполнял все свои команды вручную...

Вот почему я реализую свою собственную библиотеку run-screen. Это еще очень молодой проект (со вчерашнего дня: p), но, возможно, стоит взглянуть на него, в вашем случае это будет:

run-screen "npm run start-watch" "npm run wp-server"

Затем вы нажимаете цифровую клавишу 1, чтобы увидеть выходные данные wp-server, и нажимаете 0, чтобы увидеть выходные данные start-watch.

Ответ 17

Простой скрипт узла, который поможет вам без особых хлопот. Использование readline для объединения выходных данных, чтобы линии не были искажены.

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);
});