在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,因为我已经在另一个项目中使用了它。
我的解决方案类似于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");
})();
您应该使用npm-run-all(或并发并行shell),因为它对启动和终止命令有更多的控制权。运算符&,|是个坏主意,因为在所有测试完成后,您需要手动停止它。
这是通过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=当其中一个命令结束时,退出代码为零,则终止所有命令。
运行npm运行测试将启动Selenium驱动程序,启动http服务器(为您提供文件)并运行量角器测试。完成所有测试后,它将关闭http服务器和selenium驱动程序。
我已经从上面检查了几乎所有的解决方案,只有通过npm运行,我才能解决所有问题。与所有其他解决方案相比,主要优势是能够使用参数运行脚本。
{
"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运行all的快捷方式--并行
这允许我使用npm-run-test:watch等参数运行命令。
编辑:
对于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.
将-r添加到npm run-all脚本中,以在一个进程完成代码0时终止所有进程。当您运行HTTP服务器和另一个使用该服务器的脚本时,这尤其有用。
"test": "run-p -r test:static-server \"test:jest -- {*}\" --",
来一份老式的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,这样我就可以在以后快速扫描每个项目的所有常用命令和参数。
快速解决方案
在这种情况下,我认为最好的办法是,如果该脚本用于专用模块,只在基于*nix的机器上运行,则可以使用控制运算符来分叉进程,如下所示:&
在部分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捆绑包并行执行它们。您可以增强脚本以将分叉进程的pid输出到文件,如下所示:
"serve-bundle": "npm run bundle & echo \"$!\" > build/bundle.pid && npm run serve & echo \"$!\" > build/serve.pid && npm run open-browser",
谷歌类似于bash控件操作符,用于分叉,以了解更多关于其工作原理的信息。我还提供了一些关于在Node项目中利用Unix技术的进一步上下文:
进一步的上下文RE:Unix工具和Node.js
如果您不使用Windows,Unix工具/技术通常可以很好地使用Node脚本实现某些功能,因为:
Node.js中的很多都很好地模仿了Unix原理您使用的是*nix(包括OS X),而NPM使用的是shell
Nodeland中用于系统任务的模块通常也是Unix工具的抽象或近似,从fs到流。