想要清楚地了解NodeJS应用程序结构(完整的JavaScript堆栈)

Jus*_*nHo 34 mongodb node.js express sequelize.js mean-stack

我想知道一个典型的NodeJS应用程序的结构,因为我阅读和看到项目越多,我就越困惑,特别是对于这样的问题:(或者当我更新这个问题时甚至更多.)

  1. 以MEAN堆栈为例,据我所知,NodeJS和Express负责服务器
    部分,提供服务器接口等.MongoDB和Angular非常简单.

    业务逻辑应该在哪里?假设我有一个包含函数的controller.js,
    并且route.js文件使用此控制器函数绑定请求.我的问题是这些文件属于/运行在哪个模块下(The Express或NodeJS?)

  2. NodeJS应用程序的起点在哪里?比如index.php是php应用程序的起点,但NodeJS应用程序在哪里?我可以看到所有nodejs项目都有一个名为server.js或app.js等的文件.(包含类似的东西controller.js)但NodeJS 如何知道要查找和执行哪个文件呢?

我是NodeJS,express,sequelize.js/mongoose,jade/ejs的新手,但想要开始使用nodejs项目.你们能详细说明每个模块提供的实际功能吗?以及一个完整的js堆叠nodejs应用程序的典型结构的一般介绍?提前致谢!

Jor*_*man 41

好吧,这是一个非常广泛的问题,我绝对不是专家,但我会尽力而为.

TL; DR

  • routes 是控制器,告诉用户将浏览器导航到应用程序中的某个路径时要执行的逻辑,包括要呈现的视图以及要发送到这些视图的数据
  • models 只是 - 你的应用程序中的数据模型
  • module.exports = 告诉文件它究竟是什么"导出",即需要从主应用程序文件执行或访问的代码.
  • require(..)包括一个模块.您可以在变量上设置它,以便稍后可以调用模块函数,或者只是执行一个函数,如果全部module.exports返回的话.

结合这些技术可以帮助您确定任何应用程序的可靠框架.


答案很长

Express为构建Node.js应用程序提供了一个可靠的框架.Node完全独立于Express,但由于Express的流行程度,它们实际上是相辅相成的.安装完成后,可以使用Express生成一个脚手架Web项目(带有选项),以便您根据自己的需要进行构建.

控制器

生成的项目将创建/routes/index.js,(如果您了解MVC)基本上是您的主控制器.快递中的路线写成如下:

app.get('/path', function(req, res, next){ .. } );
Run Code Online (Sandbox Code Playgroud)

让我们打破这个:我们的应用程序变量(app)被告知在GET请求'/path'中执行带有req, res, next变量的匿名回调函数(分别是请求,响应和回调).我觉得将其视为自定义事件处理程序很有帮助.

此时需要注意的是,我们也可以app.post使用相同的语法来调用URL而不是获取.

在我们的匿名回调中,我们处理任何传入数据并为用户呈现视图.这是我的大多数业务逻辑最终的地方,所以在这里不使用匿名函数实际上是有意义的.以下是仅显示主页的基本回调示例:

app.get('/', function(req, res, next){

    //some business logic

    res.render('views/home');
});
Run Code Online (Sandbox Code Playgroud)

当用户尝试获取application(/)的索引路径时,我们只是渲染我们的home视图,从项目的根目录,它存储在一个views文件夹中.

但是,如果我们想要的模块化这让我们没有宣布所有我们的路线在我们的主要app.js还是server.js

我们module.exports = ..在模块中使用它来告诉我们的服务器究竟包含哪些内容.在我的控制器中,我导出一个函数,它将应用程序作为参数并使用它来定义我们的路由,如下所示:

控制器/ user.js的

 module.exports = function(app){

    app.get('/users', function(req, res){
        var users = req.db.collection('users').find();
        if (!users) {
            console.log("no users found");
            res.redirect('/');
        } else {
            res.render('users/index', {users : users});
        }
    });

};
Run Code Online (Sandbox Code Playgroud)

不要担心req.db代码,我将数据库附加到我的应用程序中的请求,但默认情况下不会这样做.只需了解我在这里获得"用户"列表,并将用户重定向到我的应用程序的索引(如果没有).

楷模

Mongoose为我们提供了编写模型的绝佳界面.使用猫鼬,写作模型是一个三步过程:

  • 定义架构
  • 定义模型逻辑
  • 生成并导出模型

这是一个User模型的例子:

型号/ user.js的

var mongoose = require('mongoose'),
    userSchema = new mongoose.Schema({

        name: { type: String, required: true },
        joinDate: {type: Date, default: date.now }

    }),
    User = mongoose.model('user', userSchema);

module.exports = user;
Run Code Online (Sandbox Code Playgroud)

服务器应用

module.exports用于帮助我们为代码库定义一些模块性.当我们运行节点应用程序时,我们最终运行一个JavaScript文件(您已经看过该文件server.jsapp.js).

为了防止此文件因多个模型和路由而过大,我们使用require(module)其他JS文件中的代码.module在我们的例子中,将是我们想要的模块的路径.如果您有以下doc结构:

| Controllers
    - User.js
| Models
    - User.js
| Views
app.js
Run Code Online (Sandbox Code Playgroud)

要包含您的用户控制器app.js,您可以写:require('./Controllers/User').由于我们的控制器模块只是导出函数,我们可以在require语句之后立即调用该函数,只需在末尾添加括号(无论需要什么参数).包括我的控制器看起来像这样:

require('./Controllers/User')(app)

我正在传递实际的应用程序,因为我的模块(下面)只是导出一个函数,它将业务逻辑添加到我的应用程序的路由.这只需要调用并且从不使用,所以我不会将我的控制器捕获为稍后调用方法的变量.

包含模型有点不同,因为我们可能想要执行模型定义的一些操作.我们可以通过更改我们的需求代码来做到这一点:

var User = require('./Models/User');

现在我们可以随时调用User模型的方法.Mongoose免费为我们提供了许多基本功能:

User.find({}, function(err, users){ .. });

上面的函数将找到我们所有的用户,然后执行具有潜在的匿名函数err(如果没有问题则为null),然后执行JSON格式的用户列表.很漂亮.

结合所有这些概念是如何使用Express和Node.js创建基本Web应用程序.如果有任何我可以澄清我如何使用Express的话,请在评论中告诉我.这是非常表面层面的知识,我建议深入研究文档并查看插件以扩展应用程序的功能.祝好运!