想要了解NodeJS应用程序结构(Full JavaScript Stack)

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

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

    但是业务逻辑应该去哪里? 说如果我有一个controller.js包含一个函数,
    和route.js文件绑定请求与这个控制器function。 我的问题是在哪个模块下这些文件属于/运行(Express或NodeJS?)

  2. NodeJS应用的起点在哪里? 说index.php是一个PHP应用程序的起点,但它在哪里NodeJS应用程序? 我可以看到所有nodejs项目都有一个名为server.js或app.js等的文件(包含诸如module.exports = app;类的东西)但是module.exports = app;如何知道要find并执行它的文件呢?

我是NodeJS上的一个新鲜的noob,express,sequelize.js / mongoose,jade / ejs,但是想要开始一个nodejs项目。 请大家详细说明每个模块提供的实际function,以及一个完整的js堆叠nodejs应用程序的典型结构的一般介绍? 提前致谢!

好吧,这是一个相当广泛的问题,我绝对不是专家,但我会尽我所能。

TL; DR

  • routes是控制器,告诉当用户将浏览器导航到您的应用程序中的某个path时执行什么逻辑,包括要渲染的视图以及要发送到这些视图的数据
  • models就是你的应用程序中的数据模型
  • module.exports =告诉一个文件究竟是什么“导出”,这是什么代码需要执行或从主应用程序文件访问。
  • require(..)包含一个模块。 你可以在一个variables上设置它,这样你可以在稍后调用模块函数,或者只需要执行一个函数,如果这个模块是module.exports返回的。

结合这些技术可以帮助您为任何应用程序确定一个坚实的框架。


长答案

Express为构buildNode.js应用程序提供了坚实的框架。 Node完全独立于Express,但是由于Express是多么的stream行,它们实际上是紧密相连的。 一旦安装完毕,Express可以用来生成一个脚手架Web项目(带有选项),供您根据需要进行构build。

控制器

生成的项目将创build/routes/index.js ,(如果您了解MVC)本质上是您的主要控制器 。 快递中的路线是这样写的:

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

让我们来分析一下:我们的应用程序variables(app)被告知在GET请求中使用req, res, nextvariables(request,response,callback)执行一个匿名callback函数。 我觉得这有点像一个自定义的事件处理程序。

在这一点上值得注意的是,我们也可以app.post与URL相同的语法来调用app.post而不是app.post

在我们的匿名callback中,我们处理任何传入数据并为用户呈现一个视图。 这是我的大部分业务逻辑最终的地方,所以在这里不使用匿名函数是有道理的。 下面是一个基本callback的例子,它只是显示一个主页:

 app.get('/', function(req, res, next){ //some business logic res.render('views/home'); }); 

当用户试图获取我们的应用程序( / )的索引path时,我们只需渲染我们的home视图,即从我们项目的根目录存储在views文件夹中。

但是如果我们想要模块化,那么我们不是在我们的主app.jsserver.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}); } }); }; 

不要担心req.db代码,我将数据库附加到我的应用程序中的请求,但这不是默认情况下完成的。 简单地理解,我在这里得到“用户”列表,并将用户redirect到我的应用程序的索引(如果没有的话)。

楷模

mongoose为我们提供了一个写模型的好界面。 用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; 

服务器应用

module.exports被用来帮助我们定义一些模块到我们的代码库。 当我们运行一个节点应用程序时,我们最终运行一个JavaScript文件(您已经看到了带有server.jsapp.js文件)。

为了避免这个文件在多个模型和路由中变得太大,我们使用require(module)来包含来自其他JS文件的代码。 在我们的例子中module将是我们想要的模块的path。 如果您有以下文档结构:

 | Controllers - User.js | Models - User.js | Views app.js 

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

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

我传递实际的应用程序,因为我的模块(下面)只是简单地导出一个函数,将业务逻辑添加到我的应用程序的路线。 这只需要被调用,从来没有使用,所以我不捕获我的控制器作为一个variables来调用稍后的方法。

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

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

现在我们可以随时调用我们的用户模型的方法。 mongoose为我们提供了许多免费的基础function:

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

上面的函数会去查找我们所有的用户,然后执行一个匿名函数(如果没有问题,则为null),然后执行一个具有JSON格式的用户列表。 相当漂亮。

结合所有这些概念,您将如何使用Express和Node.js创build基本Web应用程序。 如果有任何我可以澄清我如何使用快递请让我知道在评论。 这是非常表面的知识,我build议挖掘文档,并寻找插件来扩展你的应用程序的function。 祝你好运!