【问题标题】:run scripts sequentially which are watching for changes按顺序运行正在监视更改的脚本
【发布时间】:2021-11-17 09:38:55
【问题描述】:

我有一个带有脚本标签的 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 组合键停止进程时似乎出现问题,因为它不会停止进程,所以我必须关闭终端。

有没有其他方法可以让它们在查看所有 cmd 的同时按顺序运行?

【问题讨论】:

  • 所以您希望cmd2cmd1 之后执行,但cmd1 继续运行? cmd2 如何知道何时执行?
  • @Marcin 这就是我的问题。我怎样才能做到这一点?

标签: javascript npm package


【解决方案1】:

您只需将启动命令更改为:

"start": "yarn cmd1 && yarn cmd2 && yarn cmd3 && yarn cmd4"

"start": "yarn cmd1 & yarn cmd2 & yarn cmd3 & yarn cmd4 &"

这应该运行命令而不等待前一个命令完成。

可以使用命令“jobs”找到正在运行的作业。如果您需要在完成之前将它们一一杀死,可以使用命令“fg”提出。

希望一切顺利。

npm-run-all 包似乎有你要找的东西。 npm-run-all 带有 --parallel 标志

npm-run-all --parallel cmd1 cmd2 cmd3

文档说如果一个命令是单个 CTRL+C,所有正在运行的并行命令都会被终止。

请参考以下链接为每个“yarn cmd”设置名称。

https://github.com/mysticatea/npm-run-all/blob/HEAD/docs/npm-run-all.md#npm-scripts

如果您需要返回终端而不等待命令完成,另请参阅“nohup”命令。

【讨论】:

  • 抱歉,出现错误。它应该是一个 & ,以便命令按顺序运行。我已经编辑了答案。现在它应该可以正常工作了。
【解决方案2】:

您可以编写自己的 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'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-21
    • 2017-12-26
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多