Chạy hàm trong tập lệnh từ dòng lệnh (Node JS)


204

Tôi đang viết một ứng dụng web bằng Node. Nếu tôi có một số tệp JS db.jscó hàm inittrong đó thì làm sao tôi có thể gọi hàm đó từ dòng lệnh?


sử dụng npm run-func stackoverflow.com/a/43598047/696535
Pawel

3
@Pawel Tôi thích câu trả lời được chấp nhận vì nó không yêu cầu cài đặt phụ thuộc của bên thứ ba có thể mất hỗ trợ hoặc chứa lỗ hổng. Đó là một rủi ro bạn gặp phải với bất kỳ sự phụ thuộc nào, vì vậy, hạn chế sự phụ thuộc vào những người được chăm sóc và bảo trì tốt luôn là một ý tưởng tốt.
winhowes

Bạn cũng có thể sử dụng gói npmjs.com/package/invoke-script
Stefan van de Vooren

Câu trả lời:


329

Không có nhận xét về lý do tại sao bạn muốn làm điều này, hoặc những gì có thể là một thực tiễn tiêu chuẩn hơn: đây là một giải pháp cho câu hỏi của bạn .... Hãy nhớ rằng loại trích dẫn theo yêu cầu của dòng lệnh của bạn có thể thay đổi.

Trong của bạn db.js, xuất các initchức năng. Có nhiều cách, nhưng ví dụ:

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

Sau đó gọi nó như thế này, giả sử bạn db.jsđang ở trong cùng thư mục với dấu nhắc lệnh của bạn:

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

Đối với những người đọc khác, initchức năng của OP có thể được gọi là bất cứ điều gì, nó không quan trọng, nó chỉ là tên cụ thể được sử dụng trong câu hỏi.


80
Đây là một mẹo hữu ích để kiểm tra một số javascript đang chạy từ AWS lambda - cảm ơn
Alex Hinton

14
Điều gì xảy ra nếu chức năng không đồng bộ?
Augustin Riedinger

24
Trong trường hợp bất kỳ ai khác đang cố gắng thực hiện điều này trong gói.json của họ dưới dạng tập lệnh npm, tôi đã thử nó với các dấu ngoặc đơn và dấu ngoặc kép bên trong, nhưng nó không hoạt động cho đến khi tôi chuyển chúng: nút "start": "- e \ "yêu cầu ('./ máy chủ') () \" ",
Sako73

2
Cảm ơn @winhowes đã trả lời của bạn, tôi chỉ sử dụng ví dụ của bạn module.exports.init = function () { console.log('hi'); };node -e 'require("./db").init()'không làm việc cho tôi bằng cách nào đó. Tôi không chắc chắn những gì tôi đã làm sai, nhưng bằng cách làm theo ý tưởng của bạn, tôi đã sử dụng module.exports = myFunction, , và sau đó node -e 'require("./myFunction")()'làm việc cho tôi.
C.Lee

3
như một sự bổ sung cho nhận xét của @ AlexHinton, bây giờ tôi sử dụng cách sau để bắt chước một sự kiện và cuộc gọi lại : node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'. Giữa {}sẽ là bối cảnh, hãy thoải mái điều chỉnh. Ngoài ra console.log là một chút nguyên thủy nhưng một khởi đầu tốt đẹp. Tất nhiên, bạn cũng có thể viết một CLI.js dành riêng mà lần lượt yêu cầu () là index.js / handler như đã nêu trong các bình luận khác.
Adrian Föder

50

Theo các câu trả lời khác, thêm phần sau vào someFile.js

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

Sau đó bạn có thể thêm vào như sau package.json

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

Từ thiết bị đầu cuối, sau đó bạn có thể gọi

npm run myScript

Tôi thấy đây là một cách dễ dàng hơn để ghi nhớ các lệnh và sử dụng chúng


Trên máy Win10 của tôi, cú pháp này chỉ đơn giản là lặp lại tập lệnh (trong thiết bị đầu cuối PowerShell hoặc Command Prompt). Chạy trực tiếp thay vì thông qua 'npm run' ném 'Mã thông báo bất ngờ' chỉ vào điểm bắt đầu của tham số yêu cầu. Tôi chưa tìm ra cách để nó hoạt động.
CalvinDale

@CalvinDale tương tự ở đây ngoại trừ tôi có thể tự chạy tập lệnh trong powershell.
ferr

3
Trên máy của tôi (Windows 10) tôi đã phải chuyển đổi dấu ngoặc kép và dấu ngoặc đơn, như thế này: "myScript": "node -e \" yêu cầu ('./ someFile'). chỉ in ra lệnh bên trong dấu ngoặc đơn nhưng không đánh giá nó. Có lẽ điều này giải quyết các vấn đề của @CalvinDale và ferr.
Christoph

4
Điều gì xảy ra nếu chúng ta muốn thêm một đối số cho lệnh gọi hàm?
Miguel Stevens

26

Hãy thử trang điểm .

Trong db.js, thêm require('make-runnable');vào cuối.

Bây giờ bạn có thể làm:

node db.js init

Bất kỳ đối số tiếp theo sẽ được truyền cho initphương thức.


17

Chạy trực tiếp từ CLI (toàn cầu)

Tải về

npm i -g run-func

Cách sử dụng tức là chạy hàm "init", nó phải được xuất, xem phía dưới

run-func db.js init

hoặc là

Chạy từ script.json (cục bộ)

Tải về

npm i -S run-func

Thiết lập

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

Sử dụng

npm run init

Params

Bất kỳ đối số nào sau đây sẽ được truyền dưới dạng tham số hàm init(param1, param2)

run-func db.js init param1 param2

Quan trọng

hàm (trong ví dụ này init) phải được xuất trong tệp chứa nó

module.exports = { init };

hoặc xuất ES6

export { init };

Tôi đã suy nghĩ để sử dụng đề xuất của eye_mew ' make-runnable, nhưng điều này tốt hơn thế nhiều, tôi nghĩ vậy. Cảm ơn.
luis.espinal

@ luis.espinal Tôi rất vui vì bạn thấy điều này hữu ích. Có ít phép thuật trong nền và không cần sửa đổi tệp. Trừ khi một chức năng không được xuất thì nó phải như vậy, nhưng điều đó có ý nghĩa logic giống như các mô-đun ES6 thông thường và nhập / xuất của chúng.
Pawel

điều này không làm việc cho tôi; $ run-func db.js init bash: run-func: không tìm thấy lệnh
Patlatus

@Patlatus để sử dụng trực tiếp từ CLI mà không có tập lệnh trong gói.json cài đặt nó trên toàn cầunpm i -g run-func
Pawel

@Patlatus thực sự có một lỗi chỉ cho phép điều này chạy bên trong các tập lệnh pack.json. Tôi đã tải lên một phiên bản mới để sửa nó và nó cũng hoạt động trên toàn cầu
Pawel

9

cách đơn giản:

giả sử bạn có tệp db.js trong thư mục trợ giúp trong cấu trúc dự án.

Bây giờ hãy vào bên trong thư mục người trợ giúp và đi đến giao diện điều khiển nút

 helpers $ node

2) yêu cầu tệp db.js

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

3) gọi hàm của bạn (trong trường hợp của bạn là init ())

> db.init()

hi vọng điêu nay co ich


7

Nếu bạn biến db.jsthành một mô-đun, bạn có thể yêu cầu nó từ db_init.jsvà chỉ : node db_init.js.

db.js:

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

db_init.js:

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

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

7

Cái này bẩn nhưng làm việc :)

Tôi sẽ gọi main()chức năng từ kịch bản của tôi. Trước đây tôi chỉ đặt các cuộc gọi đến chính ở cuối kịch bản. Tuy nhiên tôi đã thêm một số hàm khác và xuất chúng từ tập lệnh (để sử dụng các hàm trong một số phần khác của mã) - nhưng tôi không muốn thực thi hàm main () mỗi khi tôi nhập các hàm khác trong các tập lệnh khác.

Vì vậy, tôi đã làm điều này, trong kịch bản của tôi, tôi đã loại bỏ cuộc gọi đến hàm main () và thay vào đó, ở phần cuối của kịch bản, tôi đặt kiểm tra này:

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

Vì vậy, khi tôi muốn gọi hàm đó trong CLI: node src/myScript.js main


5

Tôi làm IIFE, đại loại như thế:

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

mã này sẽ được thực thi ngay lập tức và gọi hàm init.


2
Nhưng nếu bạn chạy: node init.jsvà tệp chứa IIFE thì nó sẽ hoạt động. Tôi nghĩ rằng tôi đã không hiểu đầy đủ câu hỏi của bạn. Lấy làm tiếc.
Natan Deitch

Hoàn toàn có được điều đó, nhưng nếu mã chứa các chức năng khác, chúng có thể được gọi hoặc không được gọi
winhowes

1
Bạn thậm chí có thể đơn giản hóa nó thành (init)();nếu bạn muốn :)
Little doe

1

Đôi khi bạn muốn chạy một chức năng thông qua CLI, đôi khi bạn muốn requirenó từ một mô-đun khác. Đây là cách làm cả hai.

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

-2

Đơn giản, trong tệp javascript testfile.js:

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

Chạy tại dấu nhắc:

node testfile.js

4
Chắc chắn, điều này cho phép bạn chạy một tệp JS. Câu hỏi ban đầu nhận được khi gọi một chức năng cụ thể bên trong tệp đó mà không thay đổi luồng của tệp (trong ví dụ của bạn testđược chạy mỗi lần, vì vậy bạn phải thay đổi tệp để gọi một chức năng khác)
winhowes 28/12/17

-3

Nếu tệp của bạn chỉ chứa chức năng của bạn, ví dụ:

myFile.js:

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

Gọi nó từ dòng lệnh như thế này sẽ không có gì xảy ra:

node myFile.js

Nhưng nếu bạn thay đổi tập tin của bạn:

myFile.js:

myMethod("Hello World");

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

Bây giờ điều này sẽ làm việc từ dòng lệnh:

node myFile.js

1
Chắc chắn, đó là cách chạy tệp JS. Câu hỏi nhắm nhiều hơn vào việc liệu tôi có thể chạy một chức năng cụ thể (trong số nhiều chức năng có thể không) trong đó thay đổi duy nhất là đầu vào dòng lệnh thay vì chính tệp tin trên mỗi lệnh gọi
winhowes 18/12/17

Điều này không giải quyết được kịch bản mà người đó yêu cầu
jobmo

@jobmo, họ muốn chạy một phương thức từ dòng cmd, điều này thực hiện điều đó. (I đến đây bởi googling câu hỏi bản thân mình, vì vậy người khác có thể đánh giá cao câu trả lời), đừng lo lắng có một tập hợp đa dạng các câu trả lời bạn được phép có một sự lựa chọn
Blundell

Chính xác, câu hỏi là về việc chạy một phương thức từ dòng cmd. Trong câu trả lời này, myFile.js được thực thi. Đó là nó. Nó không thực hiện bất kỳ chức năng. Nó xảy ra sau đó tập tin có một chức năng và chức năng được gọi bên trong tập tin. Đó là quan điểm của tôi.
việc

Bạn vừa giải thích rằng câu trả lời thực thi chức năng từ dòng lệnh: +1:
Blundell
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.