เรียกใช้ฟังก์ชันในสคริปต์จากบรรทัดคำสั่ง (โหนด JS)


204

ฉันกำลังเขียนเว็บแอปในโหนด หากฉันมีไฟล์ JS ที่db.jsมีฟังก์ชันinitอยู่ฉันจะเรียกใช้ฟังก์ชันนั้นจากบรรทัดคำสั่งได้อย่างไร


ใช้ npm run-func stackoverflow.com/a/43598047/696535
Pawel

3
@ Pawel ฉันชอบคำตอบที่ยอมรับเพราะไม่จำเป็นต้องติดตั้งการพึ่งพาบุคคลที่สามซึ่งอาจสูญเสียการสนับสนุนหรือมีช่องโหว่ มันเป็นความเสี่ยงที่คุณใช้กับการพึ่งพาใด ๆ ดังนั้นการ จำกัด การพึ่งพาให้กับการตรวจสอบอย่างดีและการดูแลรักษานั้นเป็นความคิดที่ดีเสมอ
winhowes

คุณสามารถใช้แพ็คเกจnpmjs.com/package/invoke-script
Stefan van de Vooren

คำตอบ:


329

ไม่มีความคิดเห็นเกี่ยวกับสาเหตุที่คุณต้องการทำสิ่งนี้หรือสิ่งที่อาจเป็นวิธีปฏิบัติที่เป็นมาตรฐานมากขึ้น: นี่คือคำตอบสำหรับคำถามของคุณ .... โปรดจำไว้ว่าประเภทของราคาที่จำเป็นสำหรับบรรทัดคำสั่งของคุณอาจแตกต่างกันไป

ในของคุณdb.jsส่งออกinitฟังก์ชั่น มีหลายวิธี แต่ตัวอย่างเช่น:

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

จากนั้นเรียกสิ่งนี้โดยสมมติว่าคุณdb.jsอยู่ในไดเรกทอรีเดียวกับพรอมต์คำสั่งของคุณ:

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

สำหรับผู้อ่านคนอื่นinitฟังก์ชั่นของ OP อาจถูกเรียกว่าอะไรก็ได้มันไม่สำคัญมันเป็นเพียงชื่อเฉพาะที่ใช้ในคำถาม


80
นี่เป็นเคล็ดลับที่มีประโยชน์สำหรับการทดสอบจาวาสคริปต์ที่ทำงานจากแลมบ์ดา AWS - ขอบคุณ
Alex Hinton

14
จะเกิดอะไรขึ้นถ้าฟังก์ชั่น async เป็นอย่างไร
Augustin Riedinger

24
ในกรณีที่คนอื่นพยายามทำเช่นนี้ใน package.json เป็นสคริปต์ npm ฉันลองด้วยเครื่องหมายคำพูดเดี่ยวและเครื่องหมายคำพูดคู่ข้างใน แต่มันไม่ทำงานจนกว่าฉันจะเปลี่ยนมัน: "start": "node - e \ "require ('./ เซิร์ฟเวอร์') () \" ",
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 ของผมตอนนี้ใช้ต่อไปนี้เพื่อ mimick node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'เหตุการณ์และเรียกกลับ: ตรงกลาง{}จะเป็นบริบทรู้สึกอิสระที่จะปรับ ยัง console.log เป็นบิตดั้งเดิม แต่เป็นการเริ่มต้นที่ดี แน่นอนคุณยังสามารถเขียนอุทิศ CLI.js ที่จะต้อง () 's index.js / จัดการตามที่ระบุไว้ในความคิดเห็นอื่น ๆ
Adrian Föder

50

ตามคำตอบอื่น ๆ เพิ่มต่อไปนี้เพื่อ someFile.js

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

จากนั้นคุณสามารถเพิ่มสิ่งต่อไปนี้ลงใน package.json

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

จากเทอร์มินัลคุณสามารถโทรได้

npm run myScript

ฉันพบวิธีนี้ง่ายกว่ามากในการจดจำคำสั่งและใช้งาน


บนเครื่อง Win10 ของฉันไวยากรณ์นี้เป็นเพียงการสะท้อนสคริปต์ (ในเทอร์มินัล PowerShell หรือ Command Prompt) เรียกใช้โดยตรงแทนที่จะผ่าน 'npm run' จะโยน 'โทเค็นที่ไม่คาดคิด' ซึ่งชี้ไปที่จุดเริ่มต้นของพารามิเตอร์ที่ต้องการ ฉันยังไม่ทราบวิธีที่จะทำให้มันใช้งานได้
CalvinDale

@ CalvinDale เดียวกันที่นี่ยกเว้นฉันสามารถเรียกใช้สคริปต์ตัวเองใน PowerShell ได้ดี
Ferr

3
บนเครื่องของฉัน (Windows 10) ฉันต้องสลับเครื่องหมายคำพูดคู่และเดี่ยวเช่น: "myScript": "node -e \" ต้องการ ('./ someFile') someFunction () \ "" มิฉะนั้นโหนดจะ เพียงพิมพ์คำสั่งภายในเครื่องหมายคำพูดเดี่ยว แต่ไม่ประเมินค่า อาจจะแก้ปัญหาของ @CalvinDale และ ferr
Christoph

3
ถ้าเราต้องการเพิ่มอาร์กิวเมนต์ในการเรียกฟังก์ชัน
Miguel Stevens

26

ลองใช้งานได้

ใน db.js เพิ่มrequire('make-runnable');ไปยังจุดสิ้นสุด

ตอนนี้คุณสามารถทำได้:

node db.js init

args เพิ่มเติมใด ๆ จะได้รับการส่งผ่านไปยังinitวิธีการ


16

เรียกใช้โดยตรงจาก 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 };

ฉันคิดว่าจะใช้คำแนะนำของ eye_mew เพื่อใช้make-runnableแต่นี่ดีกว่ามากฉันคิด ขอบคุณ
luis.espinal

@ luis.espinal ฉันดีใจที่คุณพบว่ามีประโยชน์นี้ มีความมหัศจรรย์น้อยลงในพื้นหลังและไม่จำเป็นต้องแก้ไขไฟล์ เว้นแต่ว่าฟังก์ชั่นจะไม่ถูกส่งออกก็จะต้องมี แต่ที่ทำให้รู้สึกตรรกะเช่นเดียวกับโมดูล ES6 ปกติและการนำเข้า / ส่งออกของพวกเขา
Pawel

สิ่งนี้ไม่ได้ผลสำหรับฉัน $ run-func db.js init bash: run-func: ไม่พบคำสั่ง
Patlatus

@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.jsnode 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 มันจะทำงาน ฉันคิดว่าฉันไม่เข้าใจคำถามของคุณอย่างเต็มที่ ขอโทษ
Natan Deitch

รับทั้งหมด แต่ถ้ารหัสมีฟังก์ชั่นอื่น ๆ พวกเขาอาจจะหรืออาจจะไม่ถูกเรียกว่า
winhowes

1
คุณสามารถทำให้มันง่ายขึ้น(init)();ถ้าคุณต้องการ :)
Little doe

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:
Blundell
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.