Jak mogę uruchomić kilka skryptów npm równolegle?

W moim package.json mam te dwa skrypty:

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

Muszę uruchomić te 2 Skrypty równolegle za każdym razem, gdy zaczynam rozwijać się w Node.js. Pierwszą rzeczą, o której pomyślałem, było dodanie trzeciego skryptu, takiego jak ten:

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

... ale to będzie czekać na start-watch, aby zakończyć przed uruchomieniem wp-server.

Jak mogę je uruchomić równolegle? Proszę pamiętać, że muszę zobaczyć output z tych poleceń. Ponadto, jeśli Twoje rozwiązanie obejmuje narzędzie do budowania, wolałbym użyć gulp zamiast {[7] } ponieważ używam go już w innym projekcie.

Author: E_net4, 2015-06-20

14 answers

Użyj pakietu o nazwie jednocześnie .

npm i concurrently --save-dev

Następnie skonfiguruj swoje npm run dev zadanie tak:

"dev": "concurrently --kill-others \"npm run start-watch\" \"npm run wp-server\""
 357
Author: Neil Kistner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-12 16:31:37

Używanie pakietu jednocześnie działa, ale nie jest potrzebne do tego. Możesz po prostu użyć rury na maszynach opartych na Uniksie uruchamiających współbieżne zadania. Sugerowałbym tę metodę nad innymi, ponieważ oszczędza to od konieczności dodawania dodatkowej zależności.

"dev": "npm run start-watch | npm run wp-server"
 230
Author: Patrick Burtchaell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-29 16:30:53

Jeśli używasz środowiska UNIKSOPODOBNEGO, po prostu użyj & jako separatora:

"dev": "npm run start-watch & npm run wp-server"
W przeciwnym razie, jeśli jesteś zainteresowany rozwiązaniem wieloplatformowym, możesz użyć npm-run-all module:
"dev": "npm-run-all --parallel start-watch wp-server"
 69
Author: Diogo Cardoso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-17 11:40:45

Z Windows cmd możesz użyć start:

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

Każde polecenie uruchomione w ten sposób rozpoczyna się we własnym oknie.

 44
Author: o.v.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-02 03:41:01

Powinieneś użyć npm-run-all (lub concurrently, parallelshell), ponieważ ma większą kontrolę nad uruchamianiem i zabijaniem poleceń. Operatorzy &, | są złe pomysły, ponieważ musisz ręcznie zatrzymać go po zakończeniu wszystkich testów.

Jest to przykład badania kątomierza przez 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 = Uruchom polecenia równolegle.

-r = Zabij wszystkie polecenia, gdy jedno z nich zakończy się kodem wyjścia równym zero.

Running npm run test will start Selenium sterownik, uruchom serwer http (do serwowania plików) i uruchom testy kątomierza. Po zakończeniu wszystkich testów zostanie zamknięty serwer http i sterownik selenium.

 30
Author: nir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-29 14:51:00

Lepszym rozwiązaniem jest użycie &

"dev": "npm run start-watch & npm run wp-server"
 11
Author: Corey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 21:21:16

Sprawdziłem prawie wszystkie rozwiązania z góry i tylko z npm-run-all udało mi się rozwiązać wszystkie problemy. Główną zaletą nad wszystkimi innymi rozwiązaniami jest możliwość uruchomienia skryptu z argumentami .

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

Uwaga run-p jest skrótem od npm-run-all --paraller

Pozwala mi to na uruchamianie komend z argumentami takimi jak npm run test:watch -- Something.

EDIT:

Jest jeszcze jedna przydatna opcja dla 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.

Dodaj -r do swojego npm-run-all skrypt do zabijania wszystkich procesów po zakończeniu kodu 0. Jest to szczególnie przydatne, gdy uruchamiasz serwer HTTP i inny skrypt, który go używa.

  "test": "run-p -r test:static-server \"test:jest -- {*}\" --",
 8
Author: Darkowic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 05:50:15

Jeśli zamienisz podwójny ampersand na pojedynczy ampersand, skrypty będą działać jednocześnie.

 6
Author: Neil Girardi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 13:30:09

Mam rozwiązanie wieloplatformowe bez żadnych dodatkowych modułów . Szukałem czegoś takiego jak blok połowu próbnego, który mógłbym wykorzystać zarówno w cmd.exe i w bash.

Rozwiązaniem jest command1 || command2, który wydaje się działać w obu środowiskach tak samo. Więc rozwiązaniem dla OP jest:

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

Wtedy simple npm start (i npm run dev) będą działać na wszystkich platformach!

 6
Author: Entity Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-16 05:24:16

Szybkie Rozwiązanie

w tym przypadku, powiedziałbym, że najlepiej Jeśli ten skrypt jest dla prywatnego modułu przeznaczonego do pracy tylko na maszynach opartych na *nix , możesz użyć operatora sterującego do rozwidlania procesów, który wygląda następująco: &

Przykład zrobienia tego w częściowym pakiecie.plik 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 &"
  }

Następnie wykonywałbyś je równolegle przez npm run serve-bundle. Możesz ulepszyć skrypty, aby wypisać PID rozwidlonego procesu do pliku takiego jak więc:

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

Google coś w rodzaju operator kontroli bash for forking aby dowiedzieć się więcej o tym, jak to działa. Poniżej podałem również kilka dalszych kontekstów dotyczących wykorzystania technik uniksowych w projektach węzłów:

Dalszy kontekst RE: Unix Tools & Node.js

Jeśli nie korzystasz z systemu Windows, narzędzia / techniki uniksowe często działają dobrze, aby osiągnąć coś za pomocą skryptów węzłów, ponieważ:

  1. dużo węzła.js imituje Zasady Uniksa
  2. jesteś na *nix (incl. OS X) i NPM i tak używa powłoki

Moduły do zadań systemowych w Nodeland są również często abstrakcjami lub przybliżeniami narzędzi uniksowych, od fs do streams.

 4
Author: james_womack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 04:37:05
npm-run-all --parallel task1 task2

Edit:

Musisz mieć npm-run-all zainstalowany wcześniej. Sprawdź również tę stronę dla innych scenariuszy użycia.

 3
Author: noego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-18 13:42:39

Napotkałem problemy z & i |, które odpowiednio statusy wyjścia i rzucanie błędów.

Inne rozwiązania chcą uruchomić każde zadanie o danej nazwie, jak npm-run-all, co nie było moim przypadkiem użycia.

Więc stworzyłem npm-run-parallel, który uruchamia skrypty npm asynchronicznie i raportuje z powrotem, gdy są gotowe.

Więc, dla Twoich skryptów, będzie to:

npm-run-parallel wp-server start-watch

 2
Author: ian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-17 16:49:20

A może rozwidlenie

Inną opcją uruchamiania wielu skryptów węzłów jest skrypt pojedynczego węzła, który może widelec wiele innych. Forking jest wspierany natywnie w Node, więc nie dodaje zależności i jest wieloplatformowy.


Minimalny przykład

To po prostu uruchomi Skrypty tak, jak jest i założy, że znajdują się w katalogu skryptu nadrzędnego.

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

To uruchamiałoby skrypty z argumentami i skonfigurowany przez wiele dostępnych opcji.

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

Komunikacja z rozwidlonymi skryptami

Widełkowanie ma również dodatkową zaletę, że skrypt nadrzędny może odbierać zdarzenia od rozwidlonych procesów potomnych, a także wysyłać z powrotem. Częstym przykładem jest to, że skrypt rodzica zabija rozwidlone dzieci.

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

Więcej dostępnych zdarzeń i metod można znaleźć w ChildProcess Dokumentacja

 1
Author: Boaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-01 13:21:12

W moim przypadku mam dwa projekty, jeden to UI , a drugi to API , a oba mają własny skrypt w swoich plikach package.json.

Oto, co zrobiłem.
npm run --prefix react start&  npm run --prefix express start&
 0
Author: Vikash Mishra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 15:23:40