Ejecutar función en script desde la línea de comando (Nodo JS)


205

Estoy escribiendo una aplicación web en Node. Si tengo algún archivo JS db.jscon una función init, ¿cómo podría llamar a esa función desde la línea de comandos?



3
@Pawel Prefiero la respuesta aceptada porque no requiere instalar una dependencia de terceros que puede perder soporte o contener vulnerabilidades. Es un riesgo que corras con cualquier dependencia, por lo que limitar las dependencias a las bien examinadas y mantenidas siempre es una buena idea.
winhowes

También puede usar el paquete npmjs.com/package/invoke-script
Stefan van de Vooren

Respuestas:


330

No hay comentarios sobre por qué quiere hacer esto, o lo que podría ser una práctica más estándar: aquí hay una solución a su pregunta ... Tenga en cuenta que el tipo de citas requeridas por su línea de comando puede variar.

En su db.js, exportar la initfunción. Hay muchas formas, pero por ejemplo:

module.exports.init = function () {
  console.log('hi');
};

Luego llámelo de esta manera, suponiendo que db.jsesté en el mismo directorio que su símbolo del sistema:

node -e 'require("./db").init()'

Para otros lectores, la initfunción del OP podría haberse llamado de cualquier forma, no es importante, es solo el nombre específico utilizado en la pregunta.


80
Este fue un consejo útil para probar algunos JavaScript que se ejecutaban desde AWS lambda - gracias
Alex Hinton

14
¿Qué sucede si la función es asíncrona?
Augustin Riedinger

24
En caso de que alguien más esté tratando de hacer esto en su package.json como un script npm, lo probé con comillas simples y comillas dobles adentro, pero no funcionó hasta que las cambié: "start": "node - e \ "require ('./ server') () \" ",
Sako73

2
Gracias @winhowes por tu respuesta, acabo de usar tu ejemplo module.exports.init = function () { console.log('hi'); };y node -e 'require("./db").init()'de alguna manera no funcionó para mí. No estoy seguro de lo que hice mal, pero siguiendo su idea, usé module.exports = myFunction, y luego node -e 'require("./myFunction")()'trabajé para mí.
C.Lee

3
como un aumento de comentario de @ AlexHinton, ahora utilizo el siguiente para imitar un evento y la devolución de llamada: node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'. El medio {}sería el contexto, siéntase libre de adaptarse. También console.log es un poco primitivo pero un buen comienzo. Por supuesto, también puede escribir un CLI.js dedicado que a su vez requiera () el index.js / handler como se indica en otros comentarios.
Adrian Föder

51

Según las otras respuestas, agregue lo siguiente a someFile.js

module.exports.someFunction = function () {
  console.log('hi');
};

Luego puede agregar lo siguiente a package.json

"scripts": {
   "myScript": "node -e 'require(\"./someFile\").someFunction()'"
}

Desde la terminal, puede llamar

npm run myScript

Me parece una forma mucho más fácil de recordar los comandos y usarlos.


En mi máquina Win10, esta sintaxis simplemente hace eco del script (en un terminal PowerShell o en el símbolo del sistema). Ejecutarlo directamente en lugar de a través de 'npm run' arroja 'token inesperado' apuntando al inicio del parámetro require. Todavía no he descubierto cómo hacerlo funcionar.
CalvinDale

@ CalvinDale lo mismo aquí, excepto que puedo ejecutar el script en sí mismo en powershell.
ferr

3
En mi máquina (Windows 10) tuve que cambiar las comillas dobles y simples, así: "myScript": "node -e \" require ('./ someFile'). SomeFunction () \ "" De lo contrario, Node haría simplemente imprima el comando dentro de las comillas simples pero no lo evalúe. Tal vez esto resuelva los problemas de @CalvinDale y ferr.
Christoph

44
¿Qué pasa si queremos agregar un argumento a la llamada a la función?
Miguel Stevens

26

Prueba make-runnable .

En db.js, agregue require('make-runnable');hasta el final.

Ahora puedes hacer:

node db.js init

Cualquier argumento adicional pasaría al initmétodo.


18

Ejecutar directamente desde CLI (global)

Instalar en pc

npm i -g run-func

Uso, es decir, ejecutar la función "init", debe exportarse, ver la parte inferior

run-func db.js init

o

Ejecutar desde el script package.json (local)

Instalar en pc

npm i -S run-func

Preparar

"scripts": {
   "init": "run-func db.js init"
}

Uso

npm run init

Params

Los siguientes argumentos se pasarán como parámetros de función init(param1, param2)

run-func db.js init param1 param2

Importante

la función (en este ejemplo init) debe exportarse en el archivo que la contiene

module.exports = { init };

o exportación ES6

export { init };

Estaba pensando en usar la sugerencia de eye_mew ' make-runnable, pero creo que esto es mucho mejor que eso. Gracias.
luis.espinal

@ luis.espinal Me alegra que encuentre esto útil. Hay menos magia en el fondo y no es necesario modificar los archivos. A menos que una función no se exporte, debe ser así, pero eso tiene sentido lógico al igual que los módulos ES6 normales y su importación / exportación.
Pawel

esto no funciona para mí; $ run-func db.js init bash: run-func: comando no encontrado
Patlatus

@Patlatus para usar directamente desde CLI sin un script en package.json, instálelo globalmentenpm i -g run-func
Pawel

@Patlatus en realidad había un error que solo permitía que esto se ejecutara dentro de los scripts package.json. Subí una nueva versión que lo arregla y también funciona en todo el mundo
Pawel

9

manera simple:

supongamos que tiene el archivo db.js en un directorio de ayuda en la estructura del proyecto.

ahora vaya dentro del directorio de ayudantes y vaya a la consola del nodo

 helpers $ node

2) requiere el archivo db.js

> var db = require("./db")

3) llame a su función (en su caso, su init ())

> db.init()

espero que esto ayude


7

Si se convierte db.jsen un módulo, puede solicitarlo db_init.jsy simplemente:node db_init.js .

db.js:

module.exports = {
  method1: function () { ... },
  method2: function () { ... }
}

db_init.js:

var db = require('./db');

db.method1();
db.method2();

7

Este está sucio pero funciona :)

Estare llamando main() función desde mi script. Anteriormente solo ponía llamadas a main al final del script. Sin embargo, agregué algunas otras funciones y las exporté del script (para usar funciones en otras partes del código), pero no quiero ejecutar la función main () cada vez que importo otras funciones en otros scripts.

Así que hice esto, en mi script eliminé call to main (), y en su lugar al final del script puse esta verificación:

if (process.argv.includes('main')) {
   main();
}

Entonces, cuando quiero llamar a esa función en CLI: node src/myScript.js main


5

Hago un IIFE, algo así:

(() => init())();

Este código se ejecutará inmediatamente e invocará la función init.


2
Pero si ejecuta: node init.jsy el archivo contiene un IIFE, funcionará. Creo que no entendí completamente tu pregunta. Lo siento.
Natan Deitch

Entendí todo eso, pero si el código contiene otras funciones, pueden o no llamarse
winhowes el

1
Incluso puedes simplificarlo (init)();si quieres :)
Little doe

1

A veces desea ejecutar una función a través de CLI, a veces lo desea requiredesde otro módulo. Aquí se explica cómo hacer ambas cosas.

// file to run
const runMe = () => {}
if (require.main === module) {
  runMe()
} 
module.exports = runMe

-2

Simple, en el archivo javascript testfile.js:

module.exports.test = function () {
   console.log('hi');
};
this.test();

Ejecutando en el indicador:

node testfile.js

44
Claro, esto te permite ejecutar un archivo JS. La pregunta original es llamar a una función específica dentro de ese archivo sin cambiar el flujo del archivo (en su ejemplo testse ejecuta cada vez, por lo que tendría que cambiar el archivo para llamar a otra función)
winhowes

-3

Si su archivo solo contiene su función, por ejemplo:

myFile.js:

function myMethod(someVariable) {
    console.log(someVariable)
}

Al llamarlo desde la línea de comando así no sucederá nada:

node myFile.js

Pero si cambia su archivo:

myFile.js:

myMethod("Hello World");

function myMethod(someVariable) {
    console.log(someVariable)
}

Ahora esto funcionará desde la línea de comando:

node myFile.js

1
Claro, así es como ejecutar un archivo JS. La pregunta estaba más dirigida a si podía ejecutar una función específica (de muchas funciones posibles) donde el único cambio era la entrada de la línea de comandos en lugar del archivo JS en sí por llamada a la función
winhowes

Esto no se trata del escenario que la persona está pidiendo
jobmo

@jobmo es, quieren ejecutar un método desde la línea cmd, esto lo hace. (Llegué buscando la pregunta en Google, para que alguien más pueda apreciar la respuesta), no se preocupe, hay un conjunto diverso de respuestas que puede elegir
Blundell

Exactamente, la pregunta es acerca de ejecutar un método desde la línea cmd. En esta respuesta, myFile.js se ejecuta. Eso es todo. No está ejecutando ninguna función. Sucede entonces que el archivo tiene una función y la función se llama dentro del archivo. Ese fue mi punto.
jobmo

Acaba de explicar que la respuesta ejecuta la función desde la línea de comandos: +1:
Blundell
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.