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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5656436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:01:44  来源:igfitidea点击:

How to create my own module of functions in a node.js app

node.js

提问by Luc

I'm building my node.js app which has the following structure:

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

  • server.js
  • controllers/user.js
  • 服务器.js
  • 控制器/用户.js

server.js require the user.js controller with:

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

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

the controller/user.js file is like:

控制器/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;

This is working fine. I know want to had middleware in the Edit user function for instance so it looks like:

这工作正常。例如,我知道希望在 Edit user 函数中有中间件,所以它看起来像:

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

If I define loadUser function right above this line it's working fine. When I add all the middleware fonction in a file './lib/middleware.js' and when I try to load that file in user.js with:

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

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

this does not work and I have the error message saying that loadUser is an unknow function.

这不起作用,我收到错误消息,指出 loadUser 是一个未知函数。

Any idea ?

任何的想法 ?

** UPDATE **

** 更新 **

I have updated the files such that, in server.js (main file) I have:

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

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

In middleware.js, I then have:

在 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;
}

In controllers/user.js I have

在控制器/user.js 我有

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

When I run the app (node server.js) I then have the following error:

当我运行应用程序 (node server.js) 时,出现以下错误:

Error: PUT route /user/edit requires a callback

I am not sure to return the correct thing within middleware.js, not really familiar with module stuff yet. I also tried the "module.exports.create = create;" but same thing.

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

UPDATE WITH ANOTHER TRY

再次尝试更新

what if I create a module for the function ? In ./lib/middleware.js I would have:

如果我为函数创建一个模块怎么办?在 ./lib/middleware.js 我会有:

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

And in server, I call it:

在服务器中,我称之为:

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

It seems to me that should work but it does not...

在我看来这应该可行,但它不...

回答by Raynos

"global" scope in a file is actually module scope. Just by creating a function in a different file it does become in scope in your original file.

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

What you want to do instead is

你想要做的是

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

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

You will find that global variables actually write to modulein their scope.

你会发现全局变量实际上是module在它们的范围内写入的。

Then your function loadUser() { ... }should exist in the moduleproperty.

那么你function loadUser() { ... }应该存在于module属性中。

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

    return module;
}

If you return modulefrom your create function your returning global scope.

如果您module从 create 函数返回,则返回全局范围。

[Edit]

[编辑]

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;
}

You either need to add module.loadUser = loadUseror define loadUserin module scope. I.e. outside the createfunction.

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

[Further Edit]:

[进一步编辑]:

A standard setup would be something like:

标准设置类似于:

// middleware.js
(function() {

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

    ...

    module.exports.loadUser = loadUser;

})();

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

回答by dnewcome

When code is loaded using require() it doesn't put anything into the global context. You have to bind it to a variable.

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

For example when you require your middleware file, you are able to call create() only because the module.exports object is returned from the require() function and you are able to access the call site directly. Here is how you would keep a reference to the require()d code so you could access it later:

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

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

and probably this is what you want:

可能这就是你想要的:

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

update:As raynos pointed out, no function wrapper is advised in this case. See his comment.

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

Note that I wrapped the loadUser function reference in an anonymous function. Leaving the code as you had it would have worked as long as your code didn't rely on the value of 'this' internally.

请注意,我将 loadUser 函数引用包装在一个匿名函数中。只要您的代码在内部不依赖于“this”的值,就可以让代码保持原样。

update:I think I misunderstood what you were trying to do with create(). The above works if you define your loadUser() function as directly part of the module. If you need to do something else tricky in your Create() function you can use what I wrote above by doing something like

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

var loadUser = middleware.create();

Then you'll have the loadUser function defined in scope.

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