Как запустить несколько сценариев npm параллельно?
в своем package.json
у меня есть эти два сценария:
"scripts": {
"start-watch": "nodemon run-babel index.js",
"wp-server": "webpack-dev-server",
}
Я должен запустить эти 2 скрипта параллельно каждый раз, когда я начинаю развиваться в узел.js. Первое, о чем я подумал, это добавить третий скрипт, подобный этому:
"dev": "npm run start-watch && npm run wp-server"
... но это подождет start-watch
чтобы закончить перед запуском wp-server
.
как я могу запустить их параллельно? пожалуйста, имейте в виду, что мне нужно увидеть output
из этих команд. Кроме того, если ваш решение включает в себя инструмент сборки, я бы предпочел использовать gulp
вместо grunt
потому что я уже использовать его в другом проекте.
14 ответов
использовать пакет под названием по совместительству.
npm i concurrently --save-dev
затем Настройки npm run dev
задач как так:
"dev": "concurrently --kill-others \"npm run start-watch\" \"npm run wp-server\""
использование параллельного пакета работает, но для этого он вам не нужен. Вы можете просто использовать канал на машинах на базе UNIX, выполняющих параллельные задачи. Я бы предложил этот метод над другим, потому что он избавляет вас от необходимости добавлять дополнительную зависимость.
"dev": "npm run start-watch | npm run wp-server"
Если вы используете UNIX-подобную среду, просто используйте &
в качестве разделителя:
"dev": "npm run start-watch & npm run wp-server"
В противном случае, если вы заинтересованы в кросс-платформенном решении, вы можете использовать npm-run-all модуль:
"dev": "npm-run-all --parallel start-watch wp-server"
из Windows cmd вы можете использовать start
:
"dev": "start npm run start-watch && start npm run wp-server"
каждая команда, запущенная таким образом, запускается в своем собственном окне.
вы должны использовать npm-run-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
= запуск команд параллельно.
-r
= убить все команды, когда одна из них заканчивается кодом выхода нуль.
под управлением npm run test
запустит драйвер Selenium, запустите http-сервер (для обслуживания файлов) и запустите тесты транспортира. После завершения всех тестов он закроет http-сервер и драйвер selenium.
Я проверил почти все решения сверху и только с npm-run-all я смог решить все проблемы. Главное преимущество перед всеми другими решениями-это возможность запустить скрипт с аргументами.
{
"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
.
EDIT:
есть еще один полезный опции на 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
скрипт, чтобы убить все процессы, когда один закончил с кодом 0
. Это особенно полезно при запуске сервера HTTP и другого сценария, использующего сервер.
"test": "run-p -r test:static-server \"test:jest -- {*}\" --",
у меня есть crossplatform решение без каких-либо дополнительных модулей. Я искал что-то вроде блока try catch, который я мог бы использовать в cmd.exe и в bash.
решение command1 || command2
который, кажется, работает в обеих средах одинаковы. Таким образом, решение для OP:
"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 start
(и npm run dev
) будет работать на всех платформах!
Быстрый Решение
в этом случае, я бы сказал, лучший выбор если этот скрипт предназначен для частного модуля, предназначенного для работы только на машинах на базе *nix, вы можете использовать оператор управления для процессов разветвления, который выглядит следующим образом:&
пример выполнения этого в частичном пакете.файл 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 для раздвоения чтобы узнать больше о том, как он работает. Я также предоставил некоторый дополнительный контекст относительно использования методов Unix в проектах узлов ниже:
дальнейший контекст RE: Unix Tools & Node.js
если вы не на Windows, Unix инструменты / методы часто работают хорошо, чтобы достичь чего-то со скриптами узлов, потому что:
- много Узел.js с любовью имитирует принципы Unix
- вы на *nix (ВКЛ. OS X) и NPM использует оболочку в любом случае
fs
до streams
.npm-run-all --parallel task1 task2
изменить:
вам нужно npm-run-all заранее установлена. Также проверьте на этой странице для других сценариев использования.
я столкнулся с проблемами с &
и |
, которые выходят из статусов и ошибки метания, соответственно.
другие решения хотят запускать любую задачу с заданным именем, например npm-run-all, что не было моим вариантом использования.
Итак, я создал npm-run-parallel который запускает сценарии npm асинхронно и сообщает, когда они закончены.
Итак, для ваших сценариев это будет:
npm-run-parallel wp-server start-watch
как насчет разветвления
другой вариант запуска нескольких сценариев узлов - это сценарий с одним узлом, который может вилки многие другие. Разветвление поддерживается изначально в узле, поэтому оно не добавляет зависимостей и является кросс-платформенным.
минимальный пример
это просто запускает скрипты как есть и предполагает, что они находятся в каталоге родительского скрипта.
// 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
});
общение с раздвоенными скриптами
разветвление также имеет дополнительное преимущество, что родительский скрипт может получать события из разветвленных дочерних процессов, а также отправлять обратно. Общим примером является то, что родительский скрипт убивает своих раздвоенных детей.
runningScripts.forEach(runningScript => runningScript.kill());
для более доступных событий и методов см. ChildProcess
документация
в моем случае у меня есть два проекта, Один был UI, а другой API, и оба имеют свой собственный сценарий в своих соответствующих package.json
файлы.
Итак, вот что я сделал.
npm run --prefix react start& npm run --prefix express start&