Jalankan fungsi dalam skrip dari baris perintah (Node JS)

204

Saya sedang menulis aplikasi web di Node. Jika saya punya beberapa file JS db.jsdengan fungsi initdi dalamnya bagaimana saya bisa memanggil fungsi itu dari baris perintah?

winhowes
sumber
gunakan npm run-func stackoverflow.com/a/43598047/696535
Pawel
3
@ Pamel Saya lebih suka jawaban yang diterima karena tidak memerlukan menginstal ketergantungan pihak ketiga yang dapat kehilangan dukungan atau mengandung kerentanan. Ini adalah risiko yang Anda jalankan dengan dependensi apa pun, jadi membatasi dependensi dengan dependensi yang baik dan dipelihara selalu merupakan ide yang baik.
winhowes
Anda juga dapat menggunakan paket npmjs.com/package/invoke-script
Stefan van de Vooren

Jawaban:

329

Tidak ada komentar tentang mengapa Anda ingin melakukan ini, atau apa yang mungkin menjadi praktik yang lebih standar: di sini adalah solusi untuk pertanyaan Anda .... Ingatlah bahwa jenis kutipan yang diperlukan oleh baris perintah Anda dapat bervariasi.

Di Anda db.js, ekspor initfungsi. Ada banyak cara, tetapi misalnya:

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

Kemudian panggil seperti ini, dengan anggapan Anda db.jsberada di direktori yang sama dengan command prompt Anda:

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

Bagi pembaca lain, fungsi OP initbisa disebut apa saja, tidak penting, hanya nama spesifik yang digunakan dalam pertanyaan.

LeeGee
sumber
80
Ini adalah tip yang berguna untuk menguji beberapa javascript yang berjalan dari AWS lambda - terima kasih
Alex Hinton
14
Apa yang terjadi jika fungsinya async?
Augustin Riedinger
24
Jika ada orang lain yang mencoba melakukan ini di package.json sebagai skrip npm, saya mencobanya dengan tanda kutip tunggal, dan tanda kutip ganda di dalam, tetapi tidak berfungsi sampai saya menggantinya: "mulai": "simpul - e \ "
wajib
2
Terima kasih @winhowes atas balasan Anda, saya hanya menggunakan contoh Anda module.exports.init = function () { console.log('hi'); };Dan node -e 'require("./db").init()'entah bagaimana tidak berhasil untuk saya. Saya tidak yakin apa yang saya lakukan salah, tetapi dengan mengikuti ide Anda, saya menggunakan module.exports = myFunction, , dan kemudian node -e 'require("./myFunction")()'bekerja untuk saya.
C.Lee
3
sebagai augmentation untuk @ komentar AlexHinton, saya sekarang menggunakan berikut untuk mimick acara dan callback: node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'. Bagian tengah {}akan menjadi konteksnya, jangan ragu untuk menyesuaikan. Juga console.log agak primitif tetapi awal yang bagus. Tentu saja Anda juga dapat menulis CLI.js khusus yang pada gilirannya memerlukan () indeks.js / handler seperti yang dinyatakan dalam komentar lain.
Adrian Föder
51

Sesuai jawaban lain, tambahkan yang berikut ke someFile.js

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

Anda kemudian dapat menambahkan yang berikut ke package.json

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

Dari terminal, Anda dapat menelepon

npm run myScript

Saya menemukan ini cara yang jauh lebih mudah untuk mengingat perintah dan menggunakannya

Gaz_Edge
sumber
Pada mesin Win10 saya, sintaks ini hanya menggemakan skrip (dalam terminal PowerShell atau Command Prompt). Menjalankannya secara langsung alih-alih melalui 'npm run' melempar 'Token tak terduga' menunjuk ke awal parameter yang diperlukan. Saya belum menemukan cara untuk membuatnya bekerja.
CalvinDale
@ CalvinDale sama di sini kecuali saya bisa menjalankan skrip sendiri di PowerShell.
fer
3
Di komputer saya (Windows 10) saya harus mengganti tanda kutip ganda dan tunggal, seperti ini: "myScript": "node -e \" memerlukan ('. / SomeFile'). SomeFunction () \ "" Jika tidak, Node akan cukup cetak perintah di dalam tanda kutip tunggal tetapi tidak mengevaluasinya. Mungkin ini memecahkan masalah @CalvinDale dan ferr.
Christoph
4
Bagaimana jika kita ingin menambahkan argumen ke pemanggilan fungsi?
Miguel Stevens
26

Coba make-runnable .

Di db.js, tambahkan require('make-runnable');sampai akhir.

Sekarang Anda bisa melakukannya:

node db.js init

Argumen lebih lanjut akan diteruskan ke initmetode.

eye_mew
sumber
18

Jalankan langsung dari CLI (global)

Install

npm i -g run-func

Penggunaan yaitu menjalankan fungsi "init", itu harus diekspor, lihat bagian bawah

run-func db.js init

atau

Jalankan dari script package.json (lokal)

Install

npm i -S run-func

Mempersiapkan

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

Pemakaian

npm run init

Params

Argumen berikut akan diteruskan sebagai parameter fungsi init(param1, param2)

run-func db.js init param1 param2

Penting

fungsi (dalam contoh ini init) harus diekspor dalam file yang memuatnya

module.exports = { init };

atau ekspor ES6

export { init };
Pawel
sumber
Saya berpikir untuk menggunakan saran eye_mew 'untuk digunakan make-runnable, tetapi ini jauh lebih baik dari itu, saya pikir. Terima kasih.
luis.espinal
@ luis.espinal Saya senang Anda menemukan ini berguna. Ada sedikit keajaiban di latar belakang dan tidak perlu memodifikasi file. Kecuali suatu fungsi tidak diekspor maka itu harus, tetapi itu masuk akal secara logis seperti modul ES6 biasa dan impor / ekspornya.
Pawel
ini tidak bekerja untuk saya; $ run-func db.js init bash: run-func: perintah tidak ditemukan
Patlatus
@ Patat untuk menggunakan langsung dari CLI tanpa skrip di package.json menginstalnya secara globalnpm i -g run-func
Pawel
@ Patat sebenarnya ada bug yang hanya memungkinkan ini dijalankan di dalam script package.json. Saya mengunggah versi baru yang memperbaikinya dan berfungsi secara global juga
Pawel
9

cara sederhana:

katakanlah Anda memiliki file db.js di direktori helpers dalam struktur proyek.

sekarang masuk ke dalam direktori helpers dan pergi ke konsol node

 helpers $ node

2) membutuhkan file db.js

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

3) panggil fungsi Anda (dalam kasus Anda init ())

> db.init()

semoga ini membantu

Siyaram Malav
sumber
7

Jika Anda mengubah db.jske dalam modul Anda dapat meminta dari db_init.jsdan hanya: node db_init.js.

db.js:

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

db_init.js:

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

db.method1();
db.method2();
Dave
sumber
7

Yang ini kotor tapi berfungsi :)

Saya akan memanggil main()fungsi dari skrip saya. Sebelumnya saya hanya melakukan panggilan ke utama di akhir skrip. Namun saya memang menambahkan beberapa fungsi lain dan mengekspornya dari skrip (untuk menggunakan fungsi di beberapa bagian kode lainnya) - tetapi saya tidak ingin menjalankan fungsi main () setiap kali saya mengimpor fungsi lain di skrip lain.

Jadi saya melakukan ini, dalam skrip saya menghapus panggilan ke main (), dan sebagai gantinya di akhir skrip saya beri tanda centang:

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

Jadi ketika saya ingin memanggil fungsi itu di CLI: node src/myScript.js main

Untuk Kra
sumber
5

Saya melakukan IIFE, sesuatu seperti itu:

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

kode ini akan dieksekusi segera dan menjalankan fungsi init.

Natan Deitch
sumber
2
Tetapi jika Anda menjalankan: node init.jsdan file berisi IIFE itu akan berfungsi. Saya pikir saya tidak sepenuhnya memahami pertanyaan Anda. Maaf.
Natan Deitch
Benar-benar mendapatkan itu, tetapi jika kode tersebut berisi fungsi-fungsi lain mereka mungkin atau mungkin tidak dipanggil
winhowes
1
Anda bahkan dapat menyederhanakannya menjadi (init)();jika Anda mau :)
Little doe
1

Terkadang Anda ingin menjalankan fungsi melalui CLI, terkadang Anda ingin menjalankannya requiredari modul lain. Inilah cara melakukan keduanya.

// file to run
const runMe = () => {}
if (require.main === module) {
  runMe()
} 
module.exports = runMe
Matt K
sumber
-2

Sederhana, dalam file javascript testfile.js:

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

Berjalan saat diminta:

node testfile.js
Elton da Nobrega Mascena
sumber
4
Tentu, ini memungkinkan Anda menjalankan file JS. Pertanyaan awal mengenai memanggil fungsi tertentu di dalam file itu tanpa mengubah aliran file (dalam contoh Anda testdijalankan setiap kali, jadi Anda harus mengubah file untuk memanggil fungsi lain)
winhowes
-3

Jika file Anda hanya berisi fungsi Anda, misalnya:

myFile.js:

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

Memanggilnya dari baris perintah seperti ini tidak akan terjadi apa-apa:

node myFile.js

Tetapi jika Anda mengubah file Anda:

myFile.js:

myMethod("Hello World");

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

Sekarang ini akan berfungsi dari baris perintah:

node myFile.js
Blundell
sumber
1
Tentu, itulah cara menjalankan file JS. Pertanyaannya lebih ditujukan pada apakah saya dapat menjalankan fungsi tertentu (dari banyak fungsi yang mungkin) di mana satu-satunya perubahan adalah input baris perintah daripada file JS itu sendiri per panggilan fungsi
winhowes
Ini tidak berurusan dengan skenario yang orang tersebut minta
jobmo
@jobmo itu, mereka ingin menjalankan metode dari baris cmd, ini tidak. (saya tiba di sini dengan googling pertanyaan sendiri, jadi orang lain mungkin menghargai jawabannya), jangan khawatir ada beragam jawaban yang Anda boleh punya pilihan
Blundell
Persisnya, pertanyaannya adalah menjalankan metode dari baris cmd. Dalam jawaban ini, myFile.js dieksekusi. Itu dia. Ini tidak menjalankan fungsi apa pun. Itu terjadi kemudian bahwa file tersebut memiliki fungsi dan fungsi tersebut disebut di dalam file. Itulah poin saya.
jobmo
Anda baru saja menjelaskan bahwa jawaban menjalankan fungsi dari baris perintah: +1:
Blundell