scripts run multiple commands javascript node.js build

javascript - multiple - npm run js file



¿Cómo puedo ejecutar múltiples scripts npm en paralelo? (17)

En mi package.json tengo estos dos scripts:

"scripts": { "start-watch": "nodemon run-babel index.js", "wp-server": "webpack-dev-server", }

Tengo que ejecutar estos 2 scripts en paralelo cada vez que empiezo a desarrollar en Node.js. Lo primero que pensé fue agregar un tercer script como este:

"dev": "npm run start-watch && npm run wp-server"

... pero eso esperará a que start-watch termine antes de ejecutar wp-server .

¿Cómo puedo ejecutar estos en paralelo? Tenga en cuenta que necesito ver la output de estos comandos. Además, si su solución involucra una herramienta de compilación, prefiero usar gulp lugar de grunt porque ya lo uso en otro proyecto.


¿Qué hay de bifurcación

Otra opción para ejecutar múltiples scripts de Nodo es con un solo script de Nodo, que puede fork muchos otros. La bifurcación se admite de forma nativa en Node, por lo que no agrega dependencias y es multiplataforma.

Ejemplo mínimo

Esto solo ejecutaría los scripts tal cual y supondría que están ubicados en el directorio del script principal.

// 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));

Ejemplo detallado

Esto ejecutaría los scripts con argumentos y configurados por las muchas opciones disponibles.

// 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 });

Comunicación con guiones bifurcados

Forking también tiene el beneficio adicional de que el script primario puede recibir eventos de los procesos secundarios bifurcados, así como también enviarlos de regreso. Un ejemplo común es que el script padre mate a sus hijos bifurcados.

runningScripts.forEach(runningScript => runningScript.kill());

Para más eventos y métodos disponibles, consulte la documentación de ChildProcess


Solución rápida

En este caso, diría que la mejor opción es que si este script es para un módulo privado destinado a ejecutarse solo en máquinas basadas en * nix , puede usar el operador de control para los procesos de bifurcación, que se ve así: &

Un ejemplo de hacer esto en un archivo package.json parcial:

{ "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 &" }

Luego los ejecutarías en paralelo a través de npm run serve-bundle . Puede mejorar los scripts para generar los pids del proceso bifurcado en un archivo de esta manera:

"serve-bundle": "npm run bundle & echo /"$!/" > build/bundle.pid && npm run serve & echo /"$!/" > build/serve.pid && npm run open-browser",

Google algo así como el operador de control bash para bifurcar para aprender más sobre cómo funciona. También proporcioné un contexto adicional sobre el aprovechamiento de las técnicas de Unix en los proyectos Node a continuación:

Contexto adicional RE: Unix Tools & Node.js

Si no está en Windows, las herramientas / técnicas de Unix a menudo funcionan bien para lograr algo con los scripts de Node porque:

  1. Gran parte de Node.js imita amorosamente los principios de Unix
  2. Estás en * nix (incluido OS X) y NPM está usando un shell de todos modos

Los módulos para tareas del sistema en Nodeland también son a menudo abstracciones o aproximaciones de herramientas Unix, desde fs hasta streams .


Debe usar npm-run-all (o al concurrently , npm-run-all ), ya que tiene más control sobre los comandos de inicio y finalización. Los operadores & , | son malas ideas porque deberás detenerlo manualmente después de que todas las pruebas hayan terminado.

Este es un ejemplo para las pruebas de transportador a través de 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 = Ejecuta comandos en paralelo.

-r = Mata todos los comandos cuando uno de ellos termina con un código de salida de cero.

Al ejecutar npm run test se iniciará el controlador Selenium, se iniciará el servidor http (para servirle los archivos) y se ejecutarán pruebas de transportador. Una vez que todas las pruebas hayan finalizado, cerrará el servidor http y el controlador de selenio.


Desde cmd de windows puede usar start :

"dev": "start npm run start-watch && start npm run wp-server"

Cada comando lanzado de esta manera comienza en su propia ventana.


En mi caso, tengo dos proyectos, uno era UI y el otro era API , y ambos tienen su propio script en sus respectivos archivos package.json .

Entonces, esto es lo que hice.

npm run --prefix react start& npm run --prefix express start&


He comprobado casi todas las soluciones anteriores y solo con npm-run-all pude resolver todos los problemas. La principal ventaja sobre todas las demás soluciones es la capacidad de ejecutar secuencias de comandos con argumentos .

-r, --race - - - - - - - Set the flag to kill all tasks when a task finished with zero. This option is valid only with ''parallel'' option.

Tenga en cuenta que run-p es un acceso directo para npm-run-all --paraller

Esto me permite ejecutar comandos con argumentos como npm run test:watch -- Something .

EDITAR:

Hay una option más útil para npm-run-all :

"test": "run-p -r test:static-server /"test:jest -- {*}/" --",

Agregue -r a su npm-run-all para eliminar todos los procesos cuando uno termine con el código 0 . Esto es especialmente útil cuando ejecuta un servidor HTTP y otro script que usa el servidor.

"dev": "npm run start-watch & npm run wp-server"


He estado usando npm-run-all durante algún tiempo, pero nunca me llevé bien con él, porque la salida del comando en modo reloj no funciona bien juntos. Por ejemplo, si inicio create-react-app y jest en modo reloj, solo podré ver el resultado del último comando que ejecuté. Así que la mayoría de las veces, estaba ejecutando todos mis comandos manualmente ...

Por eso, implemento mi propia lib, run-screen . Todavía es un proyecto muy joven (de ayer: p) pero podría valer la pena mirarlo, en su caso sería:

run-screen "npm run start-watch" "npm run wp-server"

Luego presiona la tecla numérica 1 para ver la salida del wp-server y presiona 0 para ver la salida de start-watch .


Me encontré con problemas con & y | , que salen de los estados y arrojan errores, respectivamente.

Otras soluciones quieren ejecutar cualquier tarea con un nombre de pila, como npm-run-all, que no era mi caso de uso.

Así que creé npm-run-parallel que ejecuta scripts npm de forma asincrónica e informa cuando están listos.

Entonces, para sus guiones, sería:

npm-run-parallel wp-server start-watch


Puede usar uno & para secuencia de comandos de ejecución paralela

"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" }

Link de referencia


Script de nodo simple para que pueda comenzar sin demasiados problemas. Usando readline para combinar salidas para que las líneas no se rompan.

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); });


Si está utilizando un entorno similar a UNIX, simplemente use & como separador:

"dev": "npm run start-watch & npm run wp-server"

De lo contrario, si está interesado en una solución multiplataforma, puede usar el npm-run-all :

"dev": "npm-run-all --parallel start-watch wp-server"


Si reemplaza el doble ampersand con un solo ampersand, los scripts se ejecutarán simultáneamente.


Tengo una solución de plataforma cruzada sin ningún módulo adicional . Estaba buscando algo así como un bloque try catch que podría usar tanto en cmd.exe como en bash.

La solución es command1 || command2 command1 || command2 que parece funcionar en ambos entornos lo mismo. Entonces la solución para el OP es:

{ "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", }

¡Entonces npm start simple (y npm run dev ) funcionarán en todas las plataformas!


Una mejor solución es usar &

"dev": "npm run start-watch & npm run wp-server"


Usar el paquete Simultáneamente funciona, pero no lo necesita para lograrlo. Puede usar una tubería en máquinas basadas en UNIX que ejecutan tareas concurrentes. Sugeriría este método sobre el otro porque le evita tener que agregar una dependencia adicional.

"dev": "npm run start-watch > /dev/null | npm run wp-server"

nota: el primer comando tendrá su salida ignorada


Use un paquete llamado concurrently .

npm i concurrently --save-dev

Luego configure su npm run dev task de la siguiente manera:

"dev": "concurrently --kill-others /"npm run start-watch/" /"npm run wp-server/""


npm-run-all --parallel task1 task2

editar:

npm-run-all tener npm-run-all instalado de antemano. Consulte también option para ver otros escenarios de uso.