如何在node.js应用程序中创建自己的函数模块

时间:2011-04-13 22:29:29

标签: node.js

我正在构建我的node.js应用程序,它具有以下结构:

  • server.js
  • 控制器/ user.js的

server.js需要user.js控制器:

require('./controllers/user.js').route(app, mongoose);

controller / user.js文件类似于:

function route(app, mongoose){
   function route(app, mongoose){

   // Create new User item
   app.post('/user/create', function(req, res){
     ...
   }

   // Edit user
   app.put('/user/:id/edit', function(req, res){
    ...
   }

   ...
}
module.exports.route = route;

这很好用。 我知道想要在编辑用户功能中使用中间件,所以它看起来像:

...
app.put('/user/:id/edit', loadUser, function(req, res){
...

如果我在此行上方定义了loadUser函数,它可以正常工作。当我在文件'./lib/middleware.js'中添加所有中间件功能时,当我尝试在user.js中加载该文件时:

require('../lib/middleware.js').create(); // Create is the exported function

这不起作用,我有错误消息说loadUser是一个未知函数。

有什么想法吗?

**更新**

我更新了文件,在server.js(主文件)中我有:

...
var middleware = require('./lib/middleware.js');
...
require('./controllers/user.js').route(app, mongoose, middleware);
...

在middleware.js中,我有:

function create() {
  function loadUser(req, res, next) {
    // You would fetch your user from the db
    var user = users[req.params.id];
    if (user) {
      req.user = user;
      next();
    } else {
      next(new Error('Failed to load user ' + req.params.id));
    }
  }
return module;
}

在controllers / user.js中我有

function route(app, mongoose, middleware){
   ...
   // Modify an user
   app.put('/user/edit', middleware.loadUser, function(req, res){
     ...
   }
   ...
}

当我运行app(node server.js)时,我遇到以下错误:

Error: PUT route /user/edit requires a callback

我不确定在middleware.js中返回正确的东西,还不熟悉模块的东西。我也试过“module.exports.create = create;”但同样的事情。

再次尝试更新

如果我为该功能创建一个模块怎么办?在./lib/middleware.js我会:

(function(){
  var middleware = {};
  middleware.loadUser = function () {
  console.log("loadUser");
  }
  return middleware;
}());

在服务器中,我称之为:

var middleware = require('./lib/middleware.js');
middleware.loadUser;

在我看来应该有效,但事实并非......

2 个答案:

答案 0 :(得分:4)

文件中的“全局”范围实际上是模块范围。只需在不同的文件中创建一个函数,它就会成为原始文件的范围。

你要做的是

// routes.js
var middleware = require("../lib/middleware.js").create();

app.put('/user/:id/edit', middelware["loadUser"], function(req, res){

您会发现全局变量实际上写入其范围内的module

然后您的function loadUser() { ... }应该存在于module属性中。

// middleware.js
function create() { 
    ...

    return module;
}

如果从创建函数返回module,则返回全局范围。

[修改

function create() {
  function loadUser(req, res, next) {
    // You would fetch your user from the db
    var user = users[req.params.id];
    if (user) {
      req.user = user;
      next();
    } else {
      next(new Error('Failed to load user ' + req.params.id));
    }
  }
return module;
}

您需要在模块范围中添加module.loadUser = loadUser或定义loadUser。即在create函数之外。

[进一步修改]:

标准设置如下:

// middleware.js
(function() {

    function loadUser(...) {
        ...
    }

    ...

    module.exports.loadUser = loadUser;

})();

//otherfile.js
var middle = require("middleware");
middle.loadUser();

答案 1 :(得分:1)

使用require()加载代码时,它不会将任何内容放入全局上下文中。您必须将其绑定到变量。

例如,当您需要中间件文件时,您只能调用create(),因为module.exports对象是从require()函数返回的,您可以直接访问调用站点。以下是如何保留对require()d代码的引用,以便以后可以访问它:

var middleware = require('../lib/middleware.js');
middleware.create();

可能这就是你想要的:

app.put('/user/:id/edit', middleware.loadUser, function(req, res) ...

<强>更新 正如raynos指出的那样,在这种情况下不建议使用函数包装器。看他的评论。

<击> 请注意,我在一个匿名函数中包装了loadUser函数引用。只要您的代码不依赖于内部的'this'值,只要保留代码即可。

<强>更新 我想我误解了你想用create()做什么。如果您将loadUser()函数直接定义为模块的一部分,则上述方法有效。如果你需要在你的Create()函数中做一些其他棘手的事情你可以通过做类似的事情来使用我上面写的东西

var loadUser = middleware.create();

然后你将在范围内定义loadUser函数。