在package.json中,我有两个脚本:
"scripts": {
"start-watch": "nodemon run-babel index.js",
"wp-server": "webpack-dev-server",
}
每次开始在Node.js中开发时,我都必须并行运行这两个脚本。我首先想到的是添加第三个脚本,如下所示:
"dev": "npm run start-watch && npm run wp-server"
…但这将在运行wp服务器之前等待开始监视完成。
如何并行运行这些?请记住,我需要查看这些命令的输出。此外,如果您的解决方案涉及构建工具,我宁愿使用gulf而不是gulf,因为我已经在另一个项目中使用了它。
来一份老式的Makefile怎么样?
这允许您进行大量控制,包括如何管理子外壳、脚本之间的依赖关系等。
# run both scripts
start: server client
# start server and use & to background it
server:
npm run serve &
# start the client
client:
npm start
调用此Makefile,然后您可以键入
让一切开始。因为当您使用ctrl-C时,服务器命令实际上是在start命令的子进程中运行的,所以服务器命令也会停止,这与您自己在shell中备份不同。Make还可以完成命令行,至少在我使用的shell上是这样。另外,第一个命令将始终运行,因此您可以在这里自己键入make。
我总是在我的项目中加入一个makefile,这样我就可以在以后快速扫描每个项目的所有常用命令和参数。
我的解决方案类似于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");
})();
简单的节点脚本,让您无需太多麻烦。使用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);
});
分叉怎么样
运行多个节点脚本的另一种选择是使用单个节点脚本,它可以派生许多其他脚本。在Node中本机支持分叉,因此它不添加依赖项,并且是跨平台的。
最小示例
这将只是按原样运行脚本,并假设它们位于父脚本的目录中。
// 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 runningScripts= [];
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文档