Esegui la funzione nello script dalla riga di comando (Nodo JS)


205

Sto scrivendo un'app Web in Node. Se ho un file JS db.jscon una funzione inital suo interno, come potrei chiamare quella funzione dalla riga di comando?


utilizzare npm run-func stackoverflow.com/a/43598047/696535
Pawel

3
@Pawel Preferisco la risposta accettata perché non richiede l'installazione di una dipendenza di terze parti che potrebbe perdere supporto o contenere vulnerabilità. È un rischio che si corre con qualsiasi dipendenza, quindi limitare le dipendenze a quelle ben controllate e mantenute è sempre una buona idea.
mostra il

Risposte:


330

Nessun commento sul perché vuoi fare questo, o su quale potrebbe essere una pratica più standard: ecco una soluzione alla tua domanda .... Tieni presente che il tipo di virgolette richiesto dalla tua riga di comando può variare.

Nel tuo db.js, esporta la initfunzione. Ci sono molti modi, ma per esempio:

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

Quindi chiamalo in questo modo, supponendo che db.jssia nella stessa directory del prompt dei comandi:

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

Per altri lettori, la initfunzione del PO avrebbe potuto essere chiamata qualsiasi cosa, non è importante, è solo il nome specifico utilizzato nella domanda.


80
Questo è stato un suggerimento utile per testare alcuni javascript in esecuzione da AWS lambda - grazie
Alex Hinton,

14
Cosa succede se la funzione è asincrona?
Augustin Riedinger,

24
Nel caso in cui qualcun altro stia provando a farlo nel loro package.json come script npm, l'ho provato con le virgolette singole e le virgolette doppie all'interno, ma non ha funzionato fino a quando non le ho cambiate: "start": "nodo - e \ "richiedono ('./ server') () \" ",
Sako73,

2
Grazie @winhowes per la tua risposta, ho appena usato il tuo esempio module.exports.init = function () { console.log('hi'); };e node -e 'require("./db").init()'in qualche modo non ha funzionato per me. Non sono sicuro di cosa ho fatto di sbagliato, ma seguendo la tua idea ho usato module.exports = myFunction, e poi node -e 'require("./myFunction")()'ho lavorato per me.
C. Vedi

3
come un aumento a @ commento di AlexHinton, io uso il seguente per mimare un evento e il callback: node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'. Il mezzo {}sarebbe il contesto, sentiti libero di adattarmi. Anche console.log è un po 'primitivo ma un buon inizio. Ovviamente puoi anche scrivere un CLI.js dedicato che a sua volta richiede il gestore index.js / come indicato in altri commenti.
Adrian Föder,

51

Come per le altre risposte, aggiungere quanto segue a someFile.js

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

È quindi possibile aggiungere quanto segue a package.json

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

Dal terminale, è quindi possibile chiamare

npm run myScript

Trovo che sia un modo molto più semplice per ricordare i comandi e usarli


Sulla mia macchina Win10, questa sintassi fa semplicemente eco allo script (in un terminale PowerShell o Prompt dei comandi). Eseguendolo direttamente anziché tramite 'npm run' genera 'Token imprevisto' che punta all'inizio del parametro request. Non ho ancora capito come farlo funzionare.
CalvinDale,

@CalvinDale stesso qui, tranne che posso eseguire lo script stesso in PowerShell bene.
ferr

3
Sulla mia macchina (Windows 10) ho dovuto cambiare le virgolette doppie e singole, in questo modo: "myScript": "nodo -e \" richiedono ('./ someFile'). SomeFunction () \ "" Altrimenti Nodo basta stampare il comando tra virgolette singole ma non valutarlo. Forse questo risolve i problemi di @CalvinDale e Ferr.
Christoph,

4
E se vogliamo aggiungere un argomento alla chiamata della funzione?
Miguel Stevens,

26

Prova eseguibile .

In db.js, aggiungi require('make-runnable');alla fine.

Ora puoi fare:

node db.js init

Qualsiasi ulteriore argomento verrebbe passato al initmetodo.


18

Esegui direttamente dalla CLI (globale)

Installare

npm i -g run-func

Uso cioè eseguire la funzione "init", deve essere esportato, vedere il fondo

run-func db.js init

o

Esegui dallo script package.json (locale)

Installare

npm i -S run-func

Impostare

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

uso

npm run init

Parametri

Eventuali argomenti seguenti verranno passati come parametri di funzione init(param1, param2)

run-func db.js init param1 param2

Importante

la funzione (in questo esempio init) deve essere esportata nel file che la contiene

module.exports = { init };

o esportazione ES6

export { init };

Stavo pensando di usare il suggerimento di eye_mew da usare make-runnable, ma questo è molto meglio di così, penso . Grazie.
luis.espinal,

@ luis.espinal Sono contento che tu l'abbia trovato utile. C'è meno magia in background e non è necessario modificare i file. A meno che una funzione non venga esportata, deve esserlo, ma ciò ha un senso logico proprio come i normali moduli ES6 e la loro importazione / esportazione.
Pawel,

questo non funziona per me; $ run-func db.js init bash: run-func: comando non trovato
Patlatus

@Patlatus da utilizzare direttamente dalla CLI senza uno script in package.json installalo a livello globalenpm i -g run-func
Pawel

@Patlatus in realtà c'era un bug che consentiva solo l'esecuzione all'interno degli script package.json. Ho caricato una nuova versione che lo risolve e funziona anche a livello globale
Pawel,

9

modo semplice:

diciamo che hai il file db.js in una directory di helpers nella struttura del progetto.

ora vai nella directory degli helper e vai alla console del nodo

 helpers $ node

2) richiede il file db.js

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

3) chiama la tua funzione (nel tuo caso il suo init ())

> db.init()

spero che questo ti aiuti


7

Se si gira db.jsin un modulo è possibile richiedere da db_init.jse proprio: node db_init.js.

db.js:

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

db_init.js:

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

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

7

Questo è sporco ma funziona :)

Chiamerò la main()funzione dal mio script. In precedenza ho appena effettuato le chiamate al main alla fine dello script. Tuttavia, ho aggiunto alcune altre funzioni e le ho esportate dallo script (per usare le funzioni in alcune altre parti del codice) - ma non voglio eseguire la funzione main () ogni volta che importa altre funzioni in altri script.

Quindi l'ho fatto, nel mio script ho rimosso la chiamata a main () e invece alla fine dello script ho messo questo controllo:

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

Quindi, quando voglio chiamare quella funzione nella CLI: node src/myScript.js main


5

Faccio un IIFE, qualcosa del genere:

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

questo codice verrà eseguito immediatamente e invocherà la funzione init.


2
Ma se esegui: node init.jse il file contiene un IIFE funzionerà. Penso di non aver compreso appieno la tua domanda. Scusate.
Natan Deitch

Assolutamente da capire, ma se il codice contiene altre funzioni, potrebbero essere o meno chiamate
winhow

1
Puoi anche semplificarlo (init)();se vuoi :)
Piccola daina

1

A volte vuoi eseguire una funzione tramite CLI, a volte vuoi requirefarlo da un altro modulo. Ecco come fare entrambe le cose.

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

-2

Semplice, nel file javascript testfile.js:

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

In esecuzione al prompt:

node testfile.js

4
Certo, questo ti permette di eseguire un file JS. La domanda originale arriva a chiamare una funzione specifica all'interno di quel file senza cambiare il flusso del file (nel tuo esempio testviene eseguito ogni volta, quindi dovresti cambiare il file per chiamare un'altra funzione)
winhowes

-3

Se il tuo file contiene solo la tua funzione, ad esempio:

myFile.js:

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

Chiamandolo dalla riga di comando in questo modo non accadrà nulla:

node myFile.js

Ma se cambi il tuo file:

myFile.js:

myMethod("Hello World");

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

Ora funzionerà dalla riga di comando:

node myFile.js

1
Certo, ecco come eseguire un file JS. La domanda era più mirata a sapere se potevo eseguire una funzione specifica (tra le molte possibili funzioni) in cui l'unica modifica era l'input della riga di comando anziché il file JS stesso per chiamata di funzione
winhow

Non si tratta dello scenario richiesto dalla persona
jobmo

@jobmo lo è, vogliono eseguire un metodo dalla linea cmd, questo lo fa. (Sono arrivato qui cercando su Google la domanda da solo, quindi qualcun altro potrebbe apprezzare la risposta), non ti preoccupare, ci sono una serie diversificata di risposte che puoi scegliere
Blundell

Esatto, la domanda riguarda l'esecuzione di un metodo dalla riga cmd. In questa risposta, myFile.js viene eseguito. Non sta eseguendo alcuna funzione. Succede quindi che il file ha una funzione e la funzione viene chiamata all'interno del file. Questo era il mio punto.
Jobmo,

Hai appena spiegato che la risposta esegue la funzione dalla riga di comando: +1:
Blundell
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.