Truyền đối số để yêu cầu (khi tải mô-đun)


114

Có thể truyền đối số khi tải mô-đun bằng cách sử dụng request không?

Tôi có mô-đun, login.js cung cấp chức năng đăng nhập. Nó yêu cầu một kết nối cơ sở dữ liệu và tôi muốn sử dụng cùng một kết nối cơ sở dữ liệu trong tất cả các mô-đun của mình. Bây giờ tôi xuất một hàm login.setDatabase (...) cho phép tôi chỉ định kết nối cơ sở dữ liệu và hoạt động tốt. Nhưng tôi thà chuyển cơ sở dữ liệu và bất kỳ yêu cầu nào khác khi tôi tải mô-đun.

var db = ...
var login = require("./login.js")(db);

Tôi còn khá mới với NodeJS và thường phát triển bằng Java và Spring Framework, vì vậy có ... đây là một hàm tạo :) Có thể thực hiện điều gì đó giống như mã tôi đã cung cấp ở trên không?


Tôi cũng khuyên bạn nên xem câu trả lời cho câu hỏi này . Như đã chỉ ra trong câu trả lời của tôi, một thành ngữ phổ biến là chuyển appđối tượng vào các mô-đun bắt buộc.
David Weldon,

Thay vì thực hiện tất cả đối số này truyền cho db, bạn có thể sử dụng triển khai singleton và gọi db.getInstance () nếu cần.
wulfgarpro

Câu trả lời:


237

Dựa trên nhận xét của bạn trong câu trả lời này , tôi làm những gì bạn đang cố gắng làm như sau:

module.exports = function (app, db) {
    var module = {};

    module.auth = function (req, res) {
        // This will be available 'outside'.
        // Authy stuff that can be used outside...
    };

    // Other stuff...
    module.pickle = function(cucumber, herbs, vinegar) {
        // This will be available 'outside'.
        // Pickling stuff...
    };

    function jarThemPickles(pickle, jar) {
        // This will be NOT available 'outside'.
        // Pickling stuff...

        return pickleJar;
    };

    return module;
};

Tôi cấu trúc khá nhiều mô-đun của mình như vậy. Có vẻ làm việc tốt cho tôi.


apptham số cần thiết hoặc tôi có thể ommit nó? Mô-đun của tôi sẽ không sử dụng rõ ràng đối số ứng dụng này, nhưng tôi không biết liệu node.js có yêu cầu đối số này cho một số thứ nội bộ hay không. Nếu nó ổn, khai báo mô-đun của tôi sẽ như thế này:module.exports = function (db) {
Ulysses Alves

Điều đó dành riêng cho một ứng dụng Express, vì vậy chắc chắn không cần thiết.
floatingLomas

@floatingLomas Cơ chế serialization trong python được gọi là dưa: stackoverflow.com/questions/11218477/...
SadSeven

1
Vì vậy, điều gì sẽ xảy ra nếu bạn tham chiếu mô-đun nhiều lần? Đầu tiên require(mymodule)(myargs)sẽ cung cấp cho bạn một mô-đun để làm việc. Tuy nhiên nếu bạn tham chiếu nó ở một nơi khác từ một mô-đun khác ?? trong hệ thống cơ bản dường như có liên quan đến bộ nhớ cache, nhưng trong hệ thống này, bộ nhớ cache sẽ trả về phương thức trình tạo trần trong các lần gọi tiếp theo require()và nếu bạn chuyển args cho require()(someargs)bạn sẽ nhận được một mô-đun khác ... có thể tôi bị thiếu cái gì đó
Tom H

2
@TomH Trong trường hợp đó, bạn muốn lưu vào bộ nhớ cache. Để làm điều đó, bạn có thể thực hiện var module;bên ngoài chức năng xuất, và ngay sau khi bạn truy cập vào, bạn muốn kiểm tra xem modulenó đã được xác định chưa và nếu vậy, chỉ cần trả lại nó (và nếu không, hãy khởi tạo nó). Điều đó có ý nghĩa?
floatingLomas

37

Tôi không chắc liệu điều này có còn hữu ích với mọi người hay không, nhưng với ES6, tôi có một cách để làm điều đó mà tôi thấy rõ ràng và hữu ích.

class MyClass { 
  constructor ( arg1, arg2, arg3 )
  myFunction1 () {...}
  myFunction2 () {...}
  myFunction3 () {...}
}

module.exports = ( arg1, arg2, arg3 ) => { return new MyClass( arg1,arg2,arg3 ) }

Và sau đó bạn có được hành vi mong đợi của mình.

var MyClass = require('/MyClass.js')( arg1, arg2, arg3 )

32

Đúng. Trong loginmô-đun của bạn , chỉ cần xuất một hàm duy nhất lấy tham số dbcủa nó. Ví dụ:

module.exports = function(db) {
  ...
};

1
Tôi đã thử điều này. Trong login.js module.exports = function(app,db) { ... } module.exports.auth = function(req,res) { ... authentication stuff } Nó gọi hàm "vô danh" và đặt các biến appdb, nhưng khi thực hiện việc này, ứng dụng của tôi sẽ không tìm thấy authhàm. Tôi đang làm gì sai? Nếu tôi xóa chức năng ẩn danh, chức authnăng sẽ có thể truy cập lại được.
Andreas Selenwall,

Giống như mọi thứ trong javascript, exportslà một đối tượng. Bạn có thể gán thuộc tính cho nó (nhiều lần xuất) hoặc bạn có thể gán nó cho một giá trị. Có vẻ như bạn đã chỉ định xuất cho một hàm, nhưng sau đó đã gán auth làm thuộc tính của hàm mà bạn đã gán cho xuất. Vì vậy, bạn cần phải làm điều var auth = require("./login.js").authđó có thể không như bạn dự định. Nếu bạn muốn sử dụng mẫu từ câu hỏi ban đầu, có lẽ tốt nhất bạn nên gắn vào một giá trị xuất duy nhất. Nếu điều này vẫn không có ý nghĩa, tôi khuyên bạn nên đăng một ý chính để tôi xem xét.
David Weldon,

1
Sau khi đọc lại điều này, có vẻ như bạn có thể đã chỉ định authnhư một thuộc tính của exportsđối tượng, và sau đó trong mô-đun bạn đã gán exportscho một hàm (do đó ghi đè nhiệm vụ trước đó). Nếu bạn đảo ngược thứ tự của nhiệm vụ, bạn sẽ có thể truy cập vào authchức năng như mong đợi. Một lần nữa, thật khó để biết nếu không thực sự nhìn thấy mã.
David Weldon,

1
Cảm ơn sự giúp đỡ của bạn. Điều tôi không nhận ra là chính xác những gì bạn đang nhắm tới với request ('đăng nhập'). Auth. Tôi mặc dù không có sự khác biệt trong var login = require('login')var login = require('login')(app), nhưng có một sự khác biệt rất lớn, không có phép thuật nào trong hàm ẩn danh được trả về, nó chỉ là một hàm / đối tượng khác. Thay vì có a module.exports.auth, hàm anomymous bây giờ trả về hàm auth (trong số các hàm khác), tức là return { auth: authFunction, login: loginFunction}. Vì vậy, bây giờ nó hoạt động. Cảm ơn.
Andreas Selenwall,
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.