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?

winhowes
fuente
use npm run-func stackoverflow.com/a/43598047/696535
Pawel el
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.

LeeGee
fuente
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.

Gaz_Edge
fuente
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.

eye_mew
fuente
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 };
Pawel
fuente
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

Siyaram Malav
fuente
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();
Dave
fuente
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

A Kra
fuente
5

Hago un IIFE, algo así:

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

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

Natan Deitch
fuente
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
Matt K
fuente
-2

Simple, en el archivo javascript testfile.js:

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

Ejecutando en el indicador:

node testfile.js
Elton da Nobrega Mascena
fuente
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
Blundell
fuente
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