我有一个像下面这样的带有脚本标签的package.json文件。
{
"name": "name",
"version": "1.0.1",
"license": "MIT",
"scripts": {
"cmd1": "cd packages/apis/ && yarn start",
"cmd2": "cd packages/utils/ && yarn start",
"cmd3": "cd packages/components/ && yarn start",
"cmd4": "cd services/ad/ && yarn dev",
"start": "yarn cmd1 && yarn cmd2 && yarn cmd3 && yarn cmd4"
},
"dependencies": {
// dependencies listed here
}
}上面的命令按顺序运行每个命令,但发生的情况是,它等待前一个命令完成执行,然后再执行行中的下一个命令。但问题是,上面的每个命令都在监视不同的服务,以查看文件中的更改,然后相应地编译它们。因此,这意味着上面的start命令只运行第一个命令,即cmd1并观察它,而不运行其余的命令。
我尝试使用concurrently包,但它并行运行所有命令。我还查看了npm-run-all包,但在尝试使用ctrl + c组合键停止进程时,它似乎有一个问题,因为它没有停止进程,所以我必须关闭终端。
有没有其他方法可以让它们在监视所有cmds的同时按顺序运行?
发布于 2021-09-28 08:53:21
您可以编写自己的Node.js脚本来执行此操作。也许可以检查第一个命令是否发出了您正在查找的字符串(例如“服务器在http://localhost:8000/"上启动),然后执行下一条命令。
编辑:
也许这是有帮助的:
#!/usr/bin/env node
/**
* Usage:
* ./runMany.js --command COMMAND1 [AWAITED_OUTPUT_REGEX1] [--command COMMAND2 ...] ...
*/
const { exec } = require('child_process');
const args = process.argv.slice(2);
async function main() {
/** @type {{ command: string; awaitedOutput?: RegExp }[]} */
const commands = [];
for (let i = 0; i < args.length; i++) {
const el = args[i];
if (el === '--command') {
++i;
const command = args[i + 1] || '';
const awaitedOutput =
args[i + 2] === undefined || args[i + 2] === '--command'
? undefined
: (++i, new RegExp(args[i + 2]));
commands.push({ command, awaitedOutput });
}
}
console.table(commands);
let i = 0;
for (const command of commands) {
console.info(`Executing: command ${i}`);
await execute(command);
console.info(`Done: command ${i++}`);
}
}
main();
/** @type {(options: {command: string, awaitedOutput?: RegExp}) => Promise<void>} */
function execute({ command, awaitedOutput }) {
const child = exec(command);
return new Promise((resolve) => {
awaitedOutput ? console.info(`Waiting for output that matches: ${awaitedOutput}`) : resolve();
child.stdout.on('data', (data) => {
const output = data.toString();
if (awaitedOutput?.test(output)) {
resolve();
}
process.stdout.write(output);
});
child.stderr.on('data', (data) => {
const output = data.toString();
process.stderr.write(output);
});
child.on('exit', (code) => {
// if there was an error, exit
if (code) {
process.exit(code);
}
resolve();
});
});
}将其粘贴到runMany.js中,然后将其用作:
node runMany.js --command 'yarn cmd1' 'THE OUTPUT YOU ARE WAITING FOR FROM cmd1' --command 'yarn cmd2' 'THE OUTPUT YOU ARE WAITING FOR FROM cmd2' --command 'yarn cmd3' 'THE OUTPUT YOU ARE WAITING FOR FROM cmd3' --command 'yarn cmd4' 'THE OUTPUT YOU ARE WAITING FOR FROM cmd4'发布于 2021-10-01 13:14:01
您只需将start命令从:
"start": "yarn cmd1 && yarn cmd2 && yarn cmd3 && yarn cmd4"至
"start": "yarn cmd1 & yarn cmd2 & yarn cmd3 & yarn cmd4 &"这应该会在不等待前一个命令完成的情况下运行命令。
可以使用命令“job”找到正在运行的作业。如果您需要在完成之前逐个删除它们,则可以使用命令"fg“将它们带到前面。
希望它能解决问题。
包npm-run-all似乎有您正在寻找的内容。npm-run-all with --all标志
npm-run-all --parallel cmd1 cmd2 cmd3文档指出,如果一个命令是单个CTRL+C,则所有正在运行的并行命令都将被终止。
参考以下链接,为每个“纱线命令”设置一个名称。
https://github.com/mysticatea/npm-run-all/blob/HEAD/docs/npm-run-all.md#npm-scripts
如果您需要返回终端而不等待命令完成,请参阅"nohup“命令。
https://stackoverflow.com/questions/69309319
复制相似问题