私のpackage.json
には以下の2つのスクリプトがある:
"scripts": {
"start-watch": "nodemon run-babel index.js",
"wp-server": "webpack-dev-server",
}
Node.jsで開発を始めるたびに、この2つのスクリプトを並行して実行しなければなりません。最初に思いついたのは、このように3つ目のスクリプトを追加することでした:
"dev": "npm run start-watch && npm run wp-server"
しかし、これでは wp-server
を実行する前に start-watch
が終了するのを待つことになる。
**これらのコマンドの output
を見る必要があることに留意してください。また、もしあなたのソリューションがビルドツールを含むのであれば、私は grunt
の代わりに gulp
を使いたい。
Concurrentlyパッケージの使用は有効だが、その必要はない。UNIXベースのマシンではパイプを使うだけで並行タスクを実行できる。依存関係を追加しなくて済むので、私は他の方法よりもこの方法を推奨する。
"dev": "npm run start-watch > /dev/null | 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"
npm-run-all(または「現在」、「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
= 1つのコマンドが0の終了コードで終了したら、すべてのコマンドを殺します。
npm run test
を実行すると、Seleniumドライバーが起動し、httpサーバーが起動して(ファイルにサービスを提供します)、分度器テストが実行されます。 すべてのテストが完了すると、httpサーバーとセレンドライバーが閉じます。
追加のモジュールなしのクロスプラットフォームソリューションがあります。 cmd.exeとbashの両方で使用できるトライキャッチブロックのようなものを探していました。
解は「コマンド1 || 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」)がすべてのプラットフォームで動作します。!
私は上からほとんどすべてのソリューションをチェックしましたが、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」などの引数を使用してコマンドを実行できます。
編集:。
npm-run-all
にはもう1つの便利なオプションがあります。
-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 -- {*}\" --",
部分的な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コントロールオペレーターfor forking のようなもので、そのしくみの詳細を学習します。 また、以下のNodeプロジェクトでのUnix手法の活用に関して、いくつかのコンテキストを提供しました。
Windowsを使用していない場合は、Unixツール/テクニックがノードスクリプトで何かを実現するのにうまく機能することがよくあります。
1。 Node.jsの多くは、Unixの原則を愛情を込めて模倣しています。 2。 * nix(含む. OS X)とNPMはとにかくシェルを使用しています。
Nodelandのシステムタスクのモジュールは、「fs」から「streams」までのUnixツールの抽象化または近似でもあります。
複数のノードスクリプトを実行する別のオプションは、 fork他の多くのノードスクリプトを使用できる単一のノードスクリプトです。 フォーキングはノードでネイティブにサポートされているため、依存関係を追加せず、クロスプラットフォームです。
---。
これは、スクリプトをそのまま実行し、それらが親スクリプトのディレクトリにあると想定するだけです。
// 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
ドキュメントを参照してください。
私の場合、2つのプロジェクトがあります。1つは UI 、もう1つは API で、どちらもそれぞれの package.json
ファイルに独自のスクリプトを持っています。
だから、これが私がしたことです。
npm run --prefix react start& npm run --prefix express start&
npm-run-allをしばらく使用していますが、ウォッチモードでのコマンドの出力がうまく機能しないため、うまくいきませんでした。 たとえば、ウォッチモードで「create-react-app」と「jest」を起動すると、最後に実行したコマンドからの出力しか表示できなくなります。 ほとんどの場合、すべてのコマンドを手動で実行していました。..
これが、自分のlib run-screenを実装する理由です。 それはまだ非常に若いプロジェクト(昨日から:p)ですが、それを見る価値があるかもしれません。
run-screen "npm run start-watch" "npm run wp-server"
次に、数値キー「1」を押して「wp-server」の出力を確認し、「0」を押して「start-watch」の出力を確認します。
面倒なことなくあなたを動かすためのシンプルなノードスクリプト。 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);
});
私の解決策はPiittisに似ていますが、Windowsの使用に問題がありました。 したがって、win32を検証する必要がありました。
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");
})();