Birden çok npm komut dosyasını paralel olarak nasıl çalıştırabilirim?


542

Benim package.jsonbu iki senaryom var:

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

Node.js'de geliştirmeye her başladığımda bu 2 komut dosyasını paralel olarak çalıştırmam gerekiyor. Düşündüğüm ilk şey böyle üçüncü bir komut dosyası eklemekti:

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

... ama start-watchkoşmadan önce bitmesini bekleyecek wp-server.

Bunları paralel olarak nasıl çalıştırabilirim? Lütfen outputbu komutları görmem gerektiğini unutmayın . Ayrıca, çözümünüz bir oluşturma aracı içeriyorsa, gulpbunun yerine gruntzaten başka bir projede kullandığım için kullanmayı tercih ederim.


23
&&Senaryonuzu çalışacak sırayla ederken &onları çalışacaktır paralel .
vsync

Bunu yapmanın hızlı bir yolu npm run start-watch & npm run wp-server. Bu, ilk komutu arka plan iş parçacığı olarak çalıştıracaktır. Komutlardan biri uzun süre çalışmadığında ve daha sonra manuel olarak çıkılması gerekmediğinde bu gerçekten işe yarar. Gibi bir şey concurrentlyCTRL-C ile aynı anda tüm konuları öldürmek için izin verir.
Joshua Pinter

Yanıtlar:


616

Eşzamanlı olarak adlandırılan bir paket kullanın .

npm i concurrently --save-dev

Ardından npm run devgörevinizi şu şekilde ayarlayın:

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

11
node ./node_modules/concurrently/src/main.jsGerek yok. concurrentmodül için bir bin yüklediği için komut sadece iyi çalışır./node_modules/.bin/concurrent
raine

14
Orada da parallelshell . Ben aslında bir concurrentlykonsol çıkışı ile karışıklık (renkler garip gidebilir, imleç gitti olabilir) birden fazla akış kullanır, ancak bu sorunuparallelshell yok öneririz .
Stijn de Witt

3
@StijndeWitt tarafından eşzamanlı olarak bahsedilen hatalar şimdi 2.0.0 sürümünde giderilmiştir . --rawÇıktıdaki renkleri korumak için modu kullanabilirsiniz .
Kimmo

23
@StijndeWitt parallelshell, npm-run-all lehine kullanımdan kaldırıldı github.com/keithamus/…
jtzero

12
Javascript derleme / çalıştırma komut dosyalarını yönetebilmemiz için daha iyi bir yol olmalı. Bu platform için her şey birbirine bağlı görünüyor. kaçtı tırnak ve npm yapıları ile diğer 'npm çalışma' yapıları çağırmak için tırnak .. Bu oldukça acı oluyor.
Andrew T Finnell

141

UNIX benzeri bir ortam kullanıyorsanız &, ayırıcı olarak kullanmanız yeterlidir:

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

Aksi takdirde, platformlar arası bir çözümle ilgileniyorsanız, npm-run-all modülünü kullanabilirsiniz:

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

14
Bunu yaparım - zaman zaman "ctrl-c" npm, komut arka planda asılı kalır ... Herhangi bir fikir?
Kamil Tomšík

13
a && bbaşarıyla tamamlandıktan bsonra başlar a, ancak nodemon asla hatasız durmaz, bu yüzden çalışamaz. a & bbaşlar a, arka plana taşır ve bhemen başlar . Kazan! a | bstdout'unu astdinine bağlar ve bher ikisinin de aynı anda çalışmasını gerektirir. Bu istenen etkiye sahip gibi görünse de, burada kullanmamalısınız.
j2L4e

8
@ KamilTomšík süreci ayırdığı &için gerçekten kötü bir fikir. Bu npmartık ana süreç olmayacak demektir. Sonunda npm run start-watchöldürülmeyecek bir zombi alacaksınız ctrl-c.
ngryman

6
waitAsılı işlemler ile sorunu hafifletmek için ekleyin :"dev": "npm run start-watch & npm run wp-server & wait"
Ruslan Prokopchuk

2
Bu bir zombi değil. Ancak &unix'te komutun Cc / Cz'ye yanıt vermesini engeller ve ayrıca bir hata durumunda dönüş kodunun yayılmasını önler.
binki

77

Windows cmd'den şunları kullanabilirsiniz start:

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

Bu şekilde başlatılan her komut kendi penceresinde başlar.


2
Mükemmel çözüm! Yeni pencereyi açmasını seviyorum. VS2015 paketi için harika. Json ihtiyacı
TetraDev

13
İzleyici görevleriniz varsa bu çalışmaz, çünkü &&ikinci komutu başlatmadan önce ilk komutun bitmesini bekler ve bir izleyici görevi asla bitmez.
Benny Neugebauer

2
@BennyNeugebauer Komutlardan önce her komut için yeni bir komut satırı açan "start" komutu gelir. İlk başta da kafam karıştı çünkü "&& operatörünü kullanmayacaksınız" diye düşündüm. Bu çözüm çok basittir ve geliştiriciden ek paket / çalışma gerektirmez.
Addison

5
Bu yanlış. Komut sıralı olarak çalıştırılacaktır. Windows'ta komutları aynı anda çalıştırmak için bir eklenti kullanmanız gerekir.
zhekaus

1
Bu Windows'a özgü değil mi?
binki

62

Sen kullanmalıdır npm işletilen-bütün (veya concurrently, parallelshellbu başlangıç ve komutları öldürme üzerinde daha fazla kontrole sahip olduğu için). Operatörler &,| bütün testler bittikten sonra manuel olarak durdurmak gerekir çünkü kötü fikirler.

Bu, npm üzerinden iletki testi için bir örnektir:

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 = Komutları paralel olarak çalıştır.

-r = Bunlardan biri sıfır çıkış koduyla bittiğinde tüm komutları öldür.

Çalıştırılması npm run testSelenium sürücüsünü başlatır, http sunucusunu başlatır (size dosya sunmak için) ve iletki testlerini çalıştırır. Tüm testler tamamlandığında, http sunucusunu ve selenyum sürücüsünü kapatır.


3
Yine de bunun testleri yürütmek için nasıl düzgün çalıştığını merak ediyorum. Web sürücüsü başlangıç ​​ve http sunucusu paralel olarak çalışabilse de, iletki görevi yalnızca ilk ikisinden sonra çalışmalıdır.
asenovm

@asenovm siparişe bağlı görevler için, neden sadece gulpve değil gulp-sync?
r3wt

30

&Paralel çalıştırma komut dosyası için birini kullanabilirsiniz

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

Referans bağlantısı


Bu Windows'da da çalışır mı? Maalesef, düğüm için oldukça yeniyim ve bunu nasıl doğrulayacağımı bilmiyorum!
Benison Sam

@BenisonSam no, Mac üzerinde çalışıyor
shanehoban

25

Daha iyi bir çözüm kullanmak &

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

54
Hayır, daha iyi değil çünkü tüm platformlarda çalışmaz.
Stijn de Witt

Bunu bilmiyordum. Hangi platformlarda çalışmıyor? @Corey - cevabınızı inter-op uyarısıyla güncelleyin ve sizi oylayacağım
Ashley Coolman

8
&Windows üzerinde çalışır, ancak farklı çalışır. OSX'te, her iki komutu da eşzamanlı olarak çalıştıracak, ancak Windows'ta ilk komutu çalıştıracak ve ilk komutun ardından ikinci komutu çalıştıracaktır.
Trevor

3
Hayır, süreci ayırdığı için değil, basit bir şekilde öldüremezsiniz.
ngryman

2
@ngryman Ben de öyle bekliyordum. Ancak, bunu denedim ve Ctrl + C tuşlarına bastığınızda her üç işlemi de (dev, start-watch ve wp-server) öldürüyor.
musicin3d

17

Yukarıdan neredeyse tüm çözümleri kontrol ettim ve sadece npm-run-all ile tüm sorunları çözmeyi başardım. Diğer tüm çözümlere göre en büyük avantajı komut dosyasını argümanlarla çalıştırma yeteneğidir .

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

Not run-p, kısayoludurnpm-run-all --parallel

Bu benim gibi argümanlarla komut çalıştırmamı sağlar npm run test:watch -- Something.

DÜZENLE:

Bir daha kullanışlı olduğunu seçenek için 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.

Kodla işiniz bittiğinde tüm işlemleri öldürmek -riçin npm-run-allbetiğinize ekleyin 0. Bu özellikle bir HTTP sunucusu ve sunucuyu kullanan başka bir komut dosyası çalıştırdığınızda kullanışlıdır.

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

15

Ek modüller olmadan çapraz platform çözümüm var . Hem cmd.exe hem de bash kullanabilirsiniz try catch blok gibi bir şey arıyordu.

Çözüm, command1 || command2her iki ortamda da aynı gibi görünüyor. Yani OP'nin çözümü:

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

O zaman basit npm start(ve npm run dev) tüm platformlarda çalışacaktır!


11

Çift ve işareti tek bir ve işareti ile değiştirirseniz, komut dosyaları aynı anda çalışır.


Kesinlikle, basit ve zarif, bağımlılıklara veya diğer sihirlere gerek yok.
magikMaker

1
@Ginzburg Çünkü diğer cevaplarda gördüğünüz gibi tüm platformlar için aynı şekilde çalışmaz.
Jorge Fuentes González

6

Hızlı Çözüm

Bu durumda, en iyi bahsi söyleyebilirim Bu komut dosyası yalnızca * nix tabanlı makinelerde çalışması amaçlanan özel bir modül içinse, aşağıdaki gibi görünen işlemleri çatallamak için kontrol operatörünü kullanabilirsiniz:&

Bunu kısmi bir package.json dosyasında yapmaya bir örnek:

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

Daha sonra ikisini de paralel olarak yürütürdünüz npm run serve-bundle. Çatallı işlemin pids'ini aşağıdaki gibi bir dosyaya çıktılamak için komut dosyalarını geliştirebilirsiniz:

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

Google çatallama için bash kontrol operatörü gibi bir şey , nasıl çalıştığı hakkında daha fazla bilgi edinmek . Ayrıca, aşağıdaki Düğüm projelerinde Unix tekniklerinden yararlanma konusunda daha fazla bağlam sağladım:

Diğer Bağlam RE: Unix Tools & Node.js

Windows'da değilseniz, Unix araçları / teknikleri genellikle Düğüm komut dosyalarıyla bir şey elde etmek için iyi çalışır, çünkü:

  1. Node.js'nin çoğu Unix ilkelerini sevgiyle taklit ediyor
  2. * Nix kullanıyorsunuz (OS X dahil) ve NPM yine de bir kabuk kullanıyor

Nodeland sistem görevler için modüller genellikle de soyutlamalar veya Unix araçları yaklaşıklıklar vardır fsiçin streams.


1
Hayır, &operatör Windows'ta desteklenmediğinden.
Stijn de Witt

3
@StijndeWitt Yazımda "Windows'da değilseniz ..." yazıyor. Birlikte çalıştığım insanların% 0'ı, dünyanın en büyük teknoloji şirketlerinden birinde Windows'ta Düğüm çalıştırıyor. Açıkçası benim yazım hala birçok geliştirici için değerli.
james_womack

2
Yine de dairesel bir akıl yürütme yolu değil mi? Eğer bu gibi npm komut yazarsanız size olmaz muktedir o işe yaramaz çünkü Windows'u kullanın. Yani kimse Windows'u kullanmıyor, bu yüzden işe yaramıyor olması önemli değil ... Sonunda platforma bağlı bir yazılım var. Şimdi yapılması gereken şey platformlar arası yapmak çok zor ise, bunun yapılması iyi bir takas olabilir. Ancak buradaki problem , eşzamanlı ve paralel kabuk gibi standart npm betikleriyle çok kolaydır .
Stijn de Witt

2
@StijndeWitt Benim akıl yürütmemden hiçbiri dairesel değildi. Akıl yürütmenin sans bildirisini yaptım. Birçoğu Linux sunucuları üzerinde kurulan ve dağıtan Düğüm geliştiricileri için ortak teknikler gönderiyoruz. Evet, eğer bir kullanıcı ülkesi komut dosyasıysa Windows üzerinde çalışmalıdır, ancak npm komut dosyalarının çoğu geliştirme ve dağıtım içindir - çoğunlukla * nix makinelerde. Bahsettiğiniz modüller ile ilgili olarak a) eşzamanlı olarak çağırmak ve paralel standart "standart" (~ günde yaklaşık 1500 indirme NPMland'da standarttan çok uzaktır) ve b) paralel bir işlem için ek yazılıma ihtiyacınız varsa, Yudum.
james_womack

@StijndeWitt Yine de bu modüllerden haberdar edilmeyi takdir ediyorum - teşekkür ederim
james_womack

6
npm-run-all --parallel task1 task2

Düzenle:

Önceden npm-run-all kurulu olmalıdır. Ayrıca diğer kullanım senaryoları için bu sayfayı kontrol edin .


5

Çatallamaya ne dersin

Birden Düğüm komut dosyalarını çalıştırmak için bir diğer seçenek tek bir Düğüm komut ile olan çatal diğerleri. Forking, Düğümde yerel olarak desteklenir, bu nedenle bağımlılık eklemez ve çapraz platformdur.


Minimal örnek

Bu, komut dosyalarını olduğu gibi çalıştırır ve üst komut dosyasının dizininde bulunduğunu varsayar.

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

Ayrıntılı örnek

Bu, komut dosyalarını bağımsız değişkenlerle çalıştırır ve birçok seçenek tarafından yapılandırılır.

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

Çatallı komut dosyalarıyla iletişim kurma

Forking ayrıca, ana betiğin çatallı alt süreçlerden olay alabileceği ve geri gönderebileceği ek bir avantaja sahiptir. Yaygın bir örnek, ana komut dosyasının çatallı çocuklarını öldürmesidir.

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

Daha fazla kullanılabilir olay ve yöntem için belgelere bakınChildProcess


3

Sırasıyla durumlardan ve hata atmadan çıkan &ve ile ilgili sorunlar yaşadım |.

Diğer çözümler, benim kullanım durumum olmayan npm-run-all gibi belirli bir adla herhangi bir görevi çalıştırmak istiyor.

Bu yüzden npm komut dosyalarını eşzamansız olarak çalıştıran ve bittiğinde rapor veren npm-run-parallel oluşturdum .

Yani, senaryolarınız için şu olurdu:

npm-run-parallel wp-server start-watch


2

Benim durumumda, biri UI diğeri API olmak üzere iki projem var ve her ikisinin de kendi package.jsondosyalarında kendi komut dosyaları var.

İşte yaptığım şey.

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

Çözümünüz gibi. Ayrıca UI ( node app) ve API (bir alt klasör src Açısal , tahmin cd src/ng serve) var, sadece ilk bölüm çalışır. Örneğin node app& cd src& ng serve.
Jeb50


1

Npm-run-all'ı bir süredir kullanıyorum , ama hiç bir zaman anlaşamadım , çünkü saat modunda komutun çıktısı birlikte iyi çalışmıyor. Örneğin, ben başlarsak create-react-appvejest izleme modundayken, yalnızca çalıştırdığım son komutun çıktısını görebileceğim. Çoğu zaman tüm komutlarımı manuel olarak çalıştırıyordum ...

Bu yüzden kendi lib, çalışma ekranımı uyguluyorum . Hala çok genç bir proje (dünden: p) ama buna bakmaya değer olabilir, sizin durumunuzda:

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

Sonra 1çıktısını görmek için sayısal tuşa wp-serverbasın 0ve çıktısını görmek için tuşuna basın start-watch.


1

Çözümüm Piittis'e benziyor, ancak Windows kullanırken bazı sorunlar yaşadım. Bu yüzden win32 için onaylamak zorunda kaldım.

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"; // I shit you not
    }
    const myProcess = spawn(command, ["run", target]); // npm run server

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

(() => {
    runProcess("server"); // package json script
    runProcess("client");
})();

0

Çok fazla güçlük çekmeden gitmek için basit düğüm komut dosyası. Çıktıları birleştirmek için readline'ı kullanma, böylece çizgiler karışmaz.

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

0
"dev": "(cd api && start npm run start) & (cd ../client && start npm run start)"

bu çalışma pencerelerde

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.