Как я могу запустить несколько сценариев 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 -- {*}\" --",
у меня есть кроссплатформенное решение без каких-либо дополнительных модулей. Я искал что-то вроде блока 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 в проектах узлов ниже:
дополнительно контексте ре: инструменты и узлов в Unix.js
если вы не на Windows, Unix инструменты / методы часто работают хорошо, чтобы достичь чего-то с узловыми скриптами, потому что:
- много Узел.js любовно подражает принципам Unix
- вы находитесь на *nix (ВКЛ. OS X) и NPM использует оболочку в любом случае
модули для системных задач в Nodeland также часто являются абстракциями или приближениями инструментов Unix, от
fsдоstreams.
npm-run-all --parallel task1 task2edit:
вы должны иметь 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&
Comments