Executar função no script a partir da linha de comandos (Nó JS)


204

Estou escrevendo um aplicativo Web no Node. Se eu tiver algum arquivo JS db.jscom uma função init, como eu poderia chamar essa função na linha de comando?



3
@Pawel Prefiro a resposta aceita porque não requer a instalação de uma dependência de terceiros que pode perder suporte ou conter vulnerabilidades. É um risco que você corre com qualquer dependência; portanto, limitar as dependências às bem avaliadas e mantidas é sempre uma boa idéia.
Winhowes

Você também pode usar o pacote npmjs.com/package/invoke-script
Stefan van de Vooren

Respostas:


329

Não há comentários sobre o motivo pelo qual você deseja fazer isso ou qual poderia ser uma prática mais padrão: aqui está uma solução para sua pergunta ... Lembre-se de que o tipo de cotação exigido pela sua linha de comando pode variar.

No seu db.js, exporte a initfunção. Existem várias maneiras, mas por exemplo:

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

Em seguida, chame-o assim, assumindo que você db.jsesteja no mesmo diretório que seu prompt de comando:

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

Para outros leitores, a initfunção do OP poderia ter sido chamada de qualquer coisa, não é importante, é apenas o nome específico usado na pergunta.


80
Esta foi uma dica útil para testar alguns javascript que estava fugindo AWS lambda - graças
Alex Hinton

14
O que acontece se a função for assíncrona?
Augustin Riedinger 24/03

24
Caso alguém mais esteja tentando fazer isso no package.json como um script npm, tentei com aspas simples e aspas duplas, mas não funcionou até que eu as alternasse: "start": "node - e \ "require ('./ server') () \" ",
Sako73

2
Obrigado @winhowes pela sua resposta, eu apenas usei o seu exemplo module.exports.init = function () { console.log('hi'); };E node -e 'require("./db").init()'não funcionou para mim de alguma forma. Não sei ao certo o que fiz de errado, mas seguindo sua ideia, usei module.exports = myFunction, e depois node -e 'require("./myFunction")()'trabalhei para mim.
C.Lee 2/17/17

3
como um aumento para @ o comentário de AlexHinton, agora eu uso o seguinte para imitar um evento e o retorno de chamada: node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'. O meio {}seria o contexto, fique à vontade para se ajustar. O console.log também é um pouco primitivo, mas é um bom começo. Obviamente, você também pode escrever um CLI.js dedicado que, por sua vez, exija () o index.js / handler, conforme declarado em outros comentários.
Adrian Föder 30/06

50

Conforme as outras respostas, adicione o seguinte a someFile.js

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

Você pode adicionar o seguinte a package.json

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

No terminal, você pode ligar para

npm run myScript

Acho essa uma maneira muito mais fácil de lembrar dos comandos e usá-los


Na minha máquina Win10, essa sintaxe está simplesmente ecoando o script (em um terminal do PowerShell ou de prompt de comando). A execução direta em vez de via 'npm run' lança 'Token inesperado' apontando para o início do parâmetro require. Ainda não descobri como fazê-lo funcionar.
CalvinDale #

@CalvinDale mesmo aqui, exceto que eu posso executar o próprio script no PowerShell.
ferr

3
Na minha máquina (Windows 10), tive que alternar aspas duplas e simples, assim: "myScript": "node -e \" require ('./ someFile'). SomeFunction () \ "" Caso contrário, o Node basta imprimir o comando entre aspas simples, mas não avaliá-lo. Talvez isso resolva os problemas do @CalvinDale e do ferr.
Christoph

4
E se quisermos adicionar um argumento à chamada de função?
Miguel Stevens

26

Tente tornar executável .

No db.js, adicione require('make-runnable');até o final.

Agora você pode fazer:

node db.js init

Quaisquer argumentos adicionais seriam passados ​​para o initmétodo


17

Executar diretamente da CLI (global)

Instalar

npm i -g run-func

Uso ou seja, execute a função "init", ela deve ser exportada, veja o final

run-func db.js init

ou

Executar a partir do script package.json (local)

Instalar

npm i -S run-func

Configuração

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

Uso

npm run init

Params

Quaisquer argumentos a seguir serão passados ​​como parâmetros de função init(param1, param2)

run-func db.js init param1 param2

Importante

a função (neste exemplo init) deve ser exportada no arquivo que a contém

module.exports = { init };

ou exportação ES6

export { init };

Eu estava pensando em usar a sugestão de eye_mew ' make-runnable, mas isso é muito melhor do que isso, eu pensa. Obrigado.
Luis.espinal 16/17

@ luis.espinal Estou feliz que você ache isso útil. Há menos magia em segundo plano e não há necessidade de modificar arquivos. A menos que uma função não seja exportada, ela precisa ser, mas isso faz sentido lógico, assim como os módulos regulares do ES6 e sua importação / exportação.
Pawel

isso não funciona para mim; $ run-func db.js init bash: comando run-func: não encontrado
Patlatus 3/19/19

@Patlatus usar diretamente do CLI sem um script em package.json instalá-lo globalmentenpm i -g run-func
Pawel

@ Patlatus, na verdade, houve um erro que só permitia que ele fosse executado nos scripts package.json. Fiz upload de uma nova versão que correções e ele funciona globalmente muito
Pawel

9

maneira simples:

digamos que você tenha o arquivo db.js em um diretório de ajuda na estrutura do projeto.

agora entre no diretório helpers e vá para o console do nó

 helpers $ node

2) exigir arquivo db.js.

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

3) chame sua função (no seu caso, init ())

> db.init()

espero que isto ajude


7

Se você transformar db.jsem um módulo que você pode exigir que a partir db_init.jse apenas: 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á sujo, mas funciona :)

Vou chamar a main()função do meu script. Anteriormente, acabei de colocar chamadas para main no final do script. No entanto, adicionei outras funções e as exportei do script (para usar funções em outras partes do código) - mas não quero executar a função main () toda vez que importo outras funções em outros scripts.

Então eu fiz isso, no meu script eu removi a chamada para main () e, em vez disso, no final do script, coloquei esta verificação:

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

Então, quando eu quero chamar essa função na CLI: node src/myScript.js main


5

Eu faço um IIFE, algo assim:

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

este código será executado imediatamente e chamará a função init.


2
Mas se você executar: node init.jse o arquivo contiver um IIFE, ele funcionará. Eu acho que não entendi completamente sua pergunta. Desculpe.
Natan Deitch

Totalmente conseguir isso, mas se o código contém outras funções que podem ou não podem ser chamados
winhowes

1
Você pode até simplificá-lo (init)();se quiser :)
Little doe

1

Às vezes, você deseja executar uma função via CLI, outras, a requirepartir de outro módulo. Veja como fazer as duas coisas.

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

-2

Simples, no arquivo javascript testfile.js:

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

Executando no prompt:

node testfile.js

4
Claro, isso permite que você execute um arquivo JS. A pergunta original é chamar uma função específica dentro desse arquivo sem alterar o fluxo do arquivo (no seu exemplo testé executado toda vez, então você precisa alterar o arquivo para chamar outra função)
winhowes

-3

Se seu arquivo contiver apenas sua função, por exemplo:

myFile.js:

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

Chamando a partir da linha de comando como esta, nada acontecerá:

node myFile.js

Mas se você alterar seu arquivo:

myFile.js:

myMethod("Hello World");

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

Agora isso funcionará na linha de comando:

node myFile.js

1
Claro, é assim que se executa um arquivo JS. A questão foi mais destinado a se eu poderia executar uma função específica (de muitas funções possíveis) onde a única mudança foi a entrada de linha de comando em vez de arquivo JS-se por chamada de função
winhowes

Isto não é lidar com o cenário a pessoa está pedindo
jobmo

@ jobmo é, eles querem executar um método a partir da linha cmd, isso faz isso. (I chegou aqui por pesquisando a questão a mim mesmo, para que outra pessoa pode apreciar a resposta), não se preocupe, há um conjunto diversificado de respostas que você está autorizado a ter uma escolha
Blundell

Exatamente, a questão é executar um método a partir da linha cmd. Nesta resposta, o myFile.js é executado. Não está executando nenhuma função. Ocorre então que o arquivo tem uma função e a função é chamada dentro do arquivo. Esse foi o meu ponto.
jobmo

Você acabou de explicar que a resposta executa a função na linha de comando: +1:
Blundell
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.