Запустить функцию в скрипте из командной строки (Node JS)

206

Я пишу веб-приложение в Node. Если у меня есть JS-файл db.jsс функцией, initкак я могу вызвать эту функцию из командной строки?

winhowes
источник
используйте npm run-func stackoverflow.com/a/43598047/696535
Pawel
3
@Pawel Я предпочитаю принятый ответ, потому что он не требует установки сторонней зависимости, которая может либо потерять поддержку, либо содержать уязвимости. Это риск того, что вы рискуете с любой зависимостью, поэтому ограничение зависимостей хорошо проверенными и поддерживаемыми всегда является хорошей идеей.
winhowes
Вы также можете использовать пакет npmjs.com/package/invoke-script
Стефан ван де Воорен

Ответы:

331

Не комментируйте, почему вы хотите это сделать, или что может быть более стандартной практикой: вот решение вашего вопроса ... Имейте в виду, что тип кавычек, требуемый вашей командной строкой, может отличаться.

В вашем db.js, экспортируйте initфункцию. Есть много способов, но, например:

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

Затем назовите его так, предполагая, что вы находитесь db.jsв том же каталоге, что и ваша командная строка:

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

Для других читателей, initфункция OP могла бы называться как угодно, это не важно, это просто конкретное имя, используемое в вопросе.

LeeGee
источник
80
Это был полезный совет для тестирования некоторого javascript, который запускался из лямбда-AWS - спасибо
Алекс Хинтон
14
Что произойдет, если функция асинхронная?
Августин Ридингер
24
В случае, если кто-то еще пытается сделать это в своем package.json как скрипт npm, я попробовал сделать это с одинарными и двойными кавычками внутри, но это не сработало, пока я не переключил их: "start": "node - e \ "require ('./ server') () \" ",
Sako73
2
Спасибо @winhowes за твой ответ, я просто использовал твой пример module.exports.init = function () { console.log('hi'); };и node -e 'require("./db").init()'у меня не получилось как-то. Я не уверен, что я сделал неправильно, но, следуя твоей идее, я использовал module.exports = myFunction, , а затем node -e 'require("./myFunction")()'работал на меня.
C.Lee
3
как увеличение на @ комментарии AlexHinton, я теперь использовать следующее событие подражать и обратный вызов: node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'. Середина {}будет контекстом, не стесняйтесь регулировать. Также console.log немного примитивен, но хорошее начало. Конечно, вы также можете написать специальный CLI.js, который, в свою очередь, требует () индексный обработчик index.js /, как указано в других комментариях.
Адриан Фёдер
51

Согласно другим ответам, добавьте следующее к someFile.js

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

Затем вы можете добавить следующее к package.json

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

Из терминала вы можете позвонить

npm run myScript

Я считаю, что это гораздо проще запомнить команды и использовать их

Gaz_Edge
источник
На моей машине с Win10 этот синтаксис просто повторяет сценарий (в терминале PowerShell или в командной строке). Запуск его напрямую, а не через 'npm run', выдает 'неожиданный токен', указывающий на начало параметра require. Я еще не понял, как заставить это работать.
CalvinDale
@CalvinDale здесь то же самое, за исключением того, что я могу нормально запустить сам скрипт в powershell.
Ferr
3
На моей машине (Windows 10) мне пришлось переключать двойные и одинарные кавычки, например: «myScript»: «node -e \» require ('./ someFile'). SomeFunction () \ "« В противном случае Node будет просто распечатайте команду внутри одинарных кавычек, но не оценивайте ее. Может быть, это решает проблемы @CalvinDale и Ferr.
Кристоф
4
Что если мы хотим добавить аргумент в вызов функции?
Мигель Стивенс
26

Попробуйте сделать работоспособным .

В db.js добавь require('make-runnable');в конец.

Теперь вы можете сделать:

node db.js init

Любые дальнейшие аргументы будут переданы initметоду.

eye_mew
источник
18

Запускать прямо из CLI (глобально)

устанавливать

npm i -g run-func

Использование т.е. запуск функции "init", ее необходимо экспортировать, см. Внизу

run-func db.js init

или

Запустить из скрипта package.json (локальный)

устанавливать

npm i -S run-func

Настроить

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

использование

npm run init

Params

Все последующие аргументы будут переданы в качестве параметров функции init(param1, param2)

run-func db.js init param1 param2

Важный

функция (в этом примере init) должна быть экспортирована в файл, содержащий ее

module.exports = { init };

или ES6 экспорт

export { init };
Pawel
источник
Я думал использовать предложение eye_mew ' make-runnable, но это намного лучше, подумал я. Спасибо.
luis.espinal
@ luis.espinal Я рад, что вы нашли это полезным. В фоновом режиме меньше магии и нет необходимости изменять файлы. Если функция не экспортируется, то она должна быть, но это логично, как и обычные модули ES6 и их импорт / экспорт.
Павел
это не работает для меня; $ run-func db.js init bash: run-func: команда не найдена
Патлатус
@Patlatus использовать напрямую из CLI без сценария в package.json установить его глобальноnpm i -g run-func
Pawel
@Patlatus на самом деле была ошибка, которая позволяла запускать только сценарии package.json. Я загрузил новую версию, которая исправляет это, и это работает глобально
Pawel
9

простой способ:

скажем, у вас есть файл db.js в каталоге помощников в структуре проекта.

Теперь перейдите в каталог помощников и перейдите в консоль узла.

 helpers $ node

2) требуется файл db.js

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

3) вызвать вашу функцию (в вашем случае ее init ())

> db.init()

надеюсь это поможет

Сиярам Малав
источник
7

Если вы превращаетесь db.jsв модуль, вы можете потребовать его от db_init.jsи просто:node db_init.js .

db.js:

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

db_init.js:

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

db.method1();
db.method2();
Дейв
источник
7

Этот грязный, но работает :)

Я буду вызывать main()функцию из моего скрипта. Ранее я просто помещал вызовы main в конец скрипта. Однако я добавил некоторые другие функции и экспортировал их из скрипта (чтобы использовать функции в некоторых других частях кода) - но я не хочу выполнять функцию main () каждый раз, когда я импортирую другие функции в другие скрипты.

Итак, я сделал это, в моем скрипте я удалил вызов main (), и вместо этого в конце скрипта я поставил эту проверку:

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

Поэтому, когда я хочу вызвать эту функцию в CLI: node src/myScript.js main

К кра
источник
5

Я делаю IIFE, что-то вроде этого:

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

этот код будет выполнен немедленно и вызовет функцию init.

Натан Дейч
источник
2
Но если вы запустите: node init.jsи файл содержит IIFE, он будет работать. Я думаю, что я не до конца понял ваш вопрос. Сожалею.
Натан Дейч
Полностью получите это, но если код содержит другие функции, они могут или не могут быть вызваны
winhowes
1
Вы можете даже упростить это, (init)();если хотите :)
Маленькая Доу
1

Иногда вы хотите запустить функцию через CLI, иногда вы хотите использовать requireее из другого модуля. Вот как это сделать.

// file to run
const runMe = () => {}
if (require.main === module) {
  runMe()
} 
module.exports = runMe
Мэтт К
источник
-2

Просто, в файле javascript testfile.js:

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

Запуск по приглашению:

node testfile.js
Элтон да Нобрега Маскена
источник
4
Конечно, это позволяет запустить файл JS. Исходный вопрос касается вызова определенной функции внутри этого файла без изменения потока файла (в вашем примере testон запускается каждый раз, поэтому вам придется изменить файл для вызова другой функции)
winhowes
-3

Если ваш файл просто содержит вашу функцию, например:

myFile.js:

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

При его вызове из командной строки ничего не произойдет:

node myFile.js

Но если вы измените свой файл:

myFile.js:

myMethod("Hello World");

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

Теперь это будет работать из командной строки:

node myFile.js
Бландел
источник
1
Конечно, это как запустить файл JS. Вопрос был больше направлен на то, могу ли я запустить определенную функцию (из множества возможных функций), где единственным изменением был ввод командной строки, а не сам файл JS для каждого вызова функции
winhowes
Это не касается сценария, о котором просит человек
jobmo
@jobmo это так, они хотят запустить метод из строки cmd, это делает это. (я пришел сюда, погуглив вопрос сам, так что кто-то другой мог бы оценить ответ), не волнуйтесь, есть разнообразный набор ответов, у вас есть выбор
Blundell
Собственно, вопрос заключается в запуске метода из строки cmd. В этом ответе выполняется myFile.js. Это не выполнение какой-либо функции. Тогда случается, что файл имеет функцию, и функция вызывается внутри файла. Это была моя точка зрения.
jobmo
Вы только что объяснили, что ответ выполняет функцию из командной строки: +1:
Бланделл