ExpressJS如何构建应用程序?

San*_*nda 513 node.js express

我正在使用NodeJS的ExpressJS Web框架.

使用ExpressJS的人将他们的环境(开发,生产,测试......),他们的路线等放在了app.js.我认为这不是一个很好的方式,因为当你有一个很大的应用程序时,app.js太大了!

我想有这个目录结构:

| my-application
| -- app.js
| -- config/
     | -- environment.js
     | -- routes.js
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

app.js

var express = require('express');
var app = module.exports = express.createServer();

require('./config/environment.js')(app, express);
require('./config/routes.js')(app);

app.listen(3000);
Run Code Online (Sandbox Code Playgroud)

配置/ environment.js

module.exports = function(app, express){
    app.configure(function() {
    app.use(express.logger());
    });

    app.configure('development', function() {
    app.use(express.errorHandler({
        dumpExceptions: true,
        showStack: true
    }));
    });

    app.configure('production', function() {
    app.use(express.errorHandler());
    });
};
Run Code Online (Sandbox Code Playgroud)

配置/ routes.js

module.exports = function(app) {
    app.get('/', function(req, res) {
    res.send('Hello world !');
    });
};
Run Code Online (Sandbox Code Playgroud)

我的代码运行良好,我认为目录的结构很漂亮.但是,代码必须进行调整,我不确定它是好还是漂亮.

使用我的目录结构并调整代码或只使用一个文件(app.js)更好吗?

谢谢你的建议!

Pet*_*ons 294

好吧,它已经有一段时间了,这是一个很受欢迎的问题,所以我继续创建了一个带有JavaScript代码的脚手架github存储库和一个关于我如何构建一个中型express.js应用程序的漫长自述文件.

focusaurus/express_code_structure是具有最新代码的repo.拉请求欢迎.

这是README的快照,因为stackoverflow不喜欢只是一个链接的答案.我将进行一些更新,因为这是一个我将继续更新的新项目,但最终github repo将成为此信息的最新位置.


快速代码结构

该项目是如何组织中型express.js Web应用程序的示例.

目前至少表达2016年12月第4季度

建立状态

JS-标准式

你的申请有多大?

Web应用程序并不完全相同,在我看来,并不是应该应用于所有express.js应用程序的单一代码结构.

如果您的应用程序很小,则不需要这样的深层目录结构.只需保持简单,并将少量.js文件粘贴到存储库的根目录中即可.瞧.

如果您的应用程序非常庞大,那么在某些时候您需要将其分解为不同的npm包.一般来说,node.js方法似乎支持许多小包,至少对于库而言,你应该通过使用几个npm包来构建你的应用程序,因为它开始有意义并且证明了开销.因此,当您的应用程序增长并且某些部分代码在应用程序之外变得清晰可重用或者是一个清晰的子系统时,将其移动到它自己的git存储库并将其转换为独立的npm包.

因此,该项目的重点是为中型应用程序说明可行的结构.

你的整体架构是什么?

有许多方法可用于构建Web应用程序,例如

  • 服务器端MVC和Ruby on Rails
  • 单页应用程序样式a MongoDB/Express/Angular/Node(MEAN)
  • 有一些表格的基本网站
  • 模型/操作/视图/活动风格的MVC已经死了,是时候开始了
  • 以及许多其他当前和历史

每个都很适合不同的目录结构.出于这个例子的目的,它只是脚手架而不是一个完全正常工作的应用程序,但我假设以下关键架构点:

  • 该网站有一些传统的静态页面/模板
  • 该站点的"应用程序"部分是作为单页应用程序样式开发的
  • 该应用程序向浏览器公开REST/JSON样式API
  • 该应用程序模拟了一个简单的业务领域,在这种情况下,它是一个汽车经销商应用程序

那么Ruby on Rails呢?

这将是整个项目的一个主题,Ruby on Rails中体现的许多想法和他们采用的"约定优于配置"决策虽然被广泛接受和使用,但实际上并不是非常有用,有时与此存储库的相反建议.

我的主要观点是组织代码有基本原则,并且基于这些原则,Ruby on Rails约定(主要)对Ruby on Rails社区有意义.然而,只是不加思索地对这些公约进行抨击,忽略了这一点.一旦了解了基本原则,您的所有项目都将得到良好的组织和清晰:shell脚本,游戏,移动应用程序,企业项目,甚至是您的主目录.

对于Rails社区,他们希望能够有一个Rails开发人员从应用程序到应用程序切换到应用程序,并且每次都熟悉并熟悉它.如果您是37个信号或Pivotal Labs,这很有意义,并且有好处.在服务器端的JavaScript世界中,整体的风格是西方任何事情都变得越来越狂野,我们并没有真正的问题.这就是我们如何滚动.我们已经习惯了.即使在express.js中,它也是Sinatra的亲密关系,而不是Rails,从Rails获取约定通常无济于事.我甚至会说"关于配置的约定原则".

基本原则和动机

  • 精神上可以管理
    • 大脑只能同时处理和思考少量相关事物.这就是我们使用目录的原因.它通过专注于小部分来帮助我们处理复杂性.
  • 尺寸合适
    • 不要创建"Mansion目录",其中只有1个文件,仅3个目录.您可以在Ansible最佳实践中看到这种情况,这些实践将小型项目设置为创建10个以上的目录以容纳10个以上的文件,当1个目录中包含3个文件时更合适.你不开公共汽车上班(除非你是公交车司机,但即便如此你驾驶公共汽车AT工作也不能工作),所以不要创建文件系统结构,这些结构不能被其中的实际文件所证明.
  • 模块化但务实
    • 节点社区总体上支持小模块.任何可以完全从您的应用程序中分离出来的东西都应该被提取到模块中供内部使用或在npm上公开发布.但是,对于此处作为范围的中型应用程序,此开销会增加您的工作流程,而不会产生相应的价值.因此,当你有一些代理被分解出来但不足以证明一个完全独立的npm模块的时候,只需将它视为一个" 原型模块 ",期望当它超过某个大小阈值时,它将被提取出来.
    • @ hij1nx这样的人甚至包括一个app/node_modules目录,并且package.jsonproto-module目录中有文件以便于转换并充当提醒.
  • 很容易找到代码
    • 鉴于要构建的功能或要修复的错误,我们的目标是开发人员无需查找所涉及的源文件.
    • 名称有意义且准确
    • crufty代码已完全删除,不会留在孤立文件中或只是注释掉
  • 对搜索友好
    • 所有第一方源代码都在app目录中,因此您可以cd运行find/grep/xargs/ag/ack/etc而不会被第三方匹配分心
  • 使用简单明了的命名
    • npm现在似乎需要全小写的包名.我觉得这很可怕,但我必须遵循牛群,因此kebab-case即使JavaScript中的变量名必须是camelCase因为JavaScript -中的减号,文件名也应该使用.
    • 变量名称与模块路径的基本名称匹配,但kebab-case转换为camelCase
  • 按耦合分组,而不是按功能分组
    • 这是从的Ruby on Rails的惯例是一大飞跃app/views,app/controllers,app/models,等
    • 功能被添加到完整堆栈,因此我想专注于与我的功能相关的完整堆栈文件.当我向用户模型添加电话号码字段时,我不关心除用户控制器之外的任何控制器,并且我不关心除用户模型之外的任何模型.
    • 因此,不是编辑各自位于其自己目录中的6个文件而忽略这些目录中的大量其他文件,而是对此存储库进行组织,以便构建要素所需的所有文件都是共同编写的.
    • 根据MVC的性质,用户视图耦合到耦合到用户模型的用户控制器.因此,当我更改用户模型时,这3个文件通常会一起更改,但交易控制器或客户控制器会解耦,因此不会涉及.通常也适用于非MVC设计.
    • MVC或MOVE风格在哪些代码仍在鼓励哪个模块中进行解耦,但是将MVC文件传播到兄弟目录中只是令人讨厌.
    • 因此,我的每个路径文件都拥有它拥有的路径部分.routes.rb如果您想要了解应用程序中所有路径的概述,那么使用rails样式文件很方便,但是在实际构建功能和修复错误时,您只关心与要更改的部分相关的路径.
  • 在代码旁边存储测试
    • 这只是"group by coupling"的一个实例,但我想特别说出来.我已经编写了许多项目,其中测试存在于名为"tests"的并行文件系统下,现在我已经开始将测试放在与其相应代码相同的目录中,我永远不会回头.这更模块化,更容易在文本编辑器中使用,并减轻了很多"../../ .."路径的废话.如果您有疑问,请尝试几个项目并自行决定.我不会做任何事情来说服你,说服它更好.
  • 减少与事件的交叉耦合
    • 很容易想到"好的,无论何时创建新交易,我都想向所有销售人员发送电子邮件",然后只需将代码发送到创建交易的路线中.
    • 然而,这种耦合最终会将你的应用变成一个巨大的泥球.
    • 相反,DealModel应该只触发"创建"事件,而完全不知道系统可能做出的其他事情.
    • 当您以这种方式编码时,将所有与用户相关的代码放入app/users其中的可能性要大得多,因为在整个地方都没有老鼠的耦合业务逻辑嵌套来污染用户代码库的纯度.
  • 代码流是可以遵循的
    • 不要做神奇的事情.不要从文件系统中的魔术目录中自动加载文件.不要是Rails.应用程序启动时app/server.js:1,您可以按照代码查看加载和执行的所有内容.
    • 不要为您的路线制作DSL.不要求愚蠢的元编程.
    • 如果你的应用程序是如此之大,这样做magicRESTRouter.route(somecontroller, {except: 'POST'})是为你在3个基本一大胜利app.get,app.put,app.del,电话,你可能会建立一个整体的应用程序,是太大了有效工作的.喜欢BIG胜利,而不是将3条简单的线转换为1条复杂的线.
  • 使用lower-kebab-case文件名

    • 此格式可避免跨平台的文件系统区分大小写问题
    • npm禁止在新的包名中使用大写字母,这很适合

      express.js具体细节

  • 不要用app.configure.它几乎完全没用,你只是不需要它.由于无意识的copypasta,它有很多样板.

  • 快递中的中间件和路线的顺序!!!
    • 我在stackoverflow上看到的几乎每个路由问题都是无序的快速中间件
    • 一般来说,您希望您的路线分离,而不是依赖于那么多的订单
    • app.use如果您真的只需要2条路线的中间件(我正在看着你body-parser),请不要用于整个应用程序
    • 确保完成所有操作后,您确实已完成此订单:
      1. 任何超级重要的应用程序范围的中间件
      2. 所有路由和各种路由中间件
      3. 然后是错误处理程序
  • 可悲的是,受到sinatra的启发,express.js主要假设您的所有路线都将进入,server.js并且很清楚它们是如何订购的.对于中型应用程序,将事物分解为单独的路径模块是很好的,但它确实引入了无序中间件的危险

应用程序符号链接技巧

社区在Node.js的伟大要点Better local require()路径中详细介绍和讨论了许多方法.我可能很快就会选择"只处理大量的../../../ .."或使用requireFrom modlue.但是,目前,我一直在使用下面详述的符号链接技巧.

因此,避免项目内部的一种方法需要使用恼人的相对路径,例如require("../../../config")使用以下技巧:

  • 在node_modules下为您的应用创建符号链接
    • cd node_modules && ln -nsf ../app
  • 加上刚刚node_modules /应用程序符号链接本身,而不是整个文件夹node_modules,与git
    • git add -f node_modules/app
    • 是的,你的.gitignore文件中仍然应该有"node_modules"
    • 不,你不应该将"node_modules"放入你的git仓库.有些人会建议你这样做.他们是不正确的.
  • 现在,您可以使用此前缀来要求项目内模块
    • var config = require("app/config");
    • var DealModel = require("app/deals/deal-model");
  • 基本上,这使得项目内部需要的工作与外部npm模块的需求非常相似.
  • 对不起,Windows用户,你需要坚持使用父目录相对路径.

组态

通常代码模块和类只需要options传入基本的JavaScript 对象.只app/server.js应该加载app/config.js模块.从那里它可以合成小options对象以根据需要配置子系统,但是将每个子系统耦合到充满额外信息的大型全局配置模块是不良耦合.

尝试集中创建数据库连接并将其传递到子系统,而不是传递连接参数,并让子系统自己进行传出连接.

NODE_ENV

这是从Rails继承的另一个诱人但可怕的想法.您的应用中应该只有一个位置,app/config.js它会查看NODE_ENV环境变量.其他所有内容都应该作为类构造函数参数或模块配置参数使用显式选项.

如果电子邮件模块有关于如何传递电子邮件(SMTP,登录到stdout,放入队列等)的选项,它应该采取类似的选项,{deliver: 'stdout'}但它绝对不应该检查NODE_ENV.

测试

我现在将我的测试文件保存在与其相应代码相同的目录中,并使用文件扩展名命名约定来区分测试和生产代码.

  • foo.js 有模块"foo"的代码
  • foo.tape.js 有foo的基于节点的测试,并且生活在同一个目录中
  • foo.btape.js 可用于需要在浏览器环境中执行的测试

我使用filesystem globs和find . -name '*.tape.js'命令来访问我所有的测试.

如何在每个.js模块文件中组织代码

这个项目的范围主要是关于文件和目录的位置,我不想添加很多其他范围,但我只想提一下,我将我的代码组织成3个不同的部分.

  1. CommonJS的打开块需要调用状态依赖项
  2. 纯JavaScript的主要代码块.这里没有CommonJS污染.不要引用导出,模块或要求.
  3. 关闭CommonJS块以设置导出

  • 我找到了我在这里寻找的东西:http://stackoverflow.com/questions/12418372/node-js-express-correct-use-of-bodyparser-middleware/12418799#12418799 (3认同)
  • 关于**app符号链接技巧**,有[这个](https://github.com/ilearnio/module-alias)小模块,它会让所有问题都消失 (2认同)

Pet*_*ons 156

更新(2013-10-29):请参阅我的其他答案,其中包括JavaScript而不是CoffeeScript受欢迎的需求以及样板github repo和广泛的README详细说明了我对此主题的最新建议.

配置

你做的很好.我喜欢在具有config.coffee嵌套命名空间的顶级文件中设置我自己的config命名空间.

#Set the current environment to true in the env object
currentEnv = process.env.NODE_ENV or 'development'
exports.appName = "MyApp"
exports.env =
  production: false
  staging: false
  test: false
  development: false
exports.env[currentEnv] = true
exports.log =
  path: __dirname + "/var/log/app_#{currentEnv}.log"
exports.server =
  port: 9600
  #In staging and production, listen loopback. nginx listens on the network.
  ip: '127.0.0.1'
if currentEnv not in ['production', 'staging']
  exports.enableTests = true
  #Listen on all IPs in dev/test (for testing from other machines)
  exports.server.ip = '0.0.0.0'
exports.db =
  URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"
Run Code Online (Sandbox Code Playgroud)

这对系统管理员编辑很友好.然后当我需要某些东西时,比如数据库连接信息,它就是

require('./config').db.URL
Run Code Online (Sandbox Code Playgroud)

路线/控制器

我喜欢将我的路由留给我的控制器并将它们组织在一个app/controllers子目录中.然后我可以加载它们并让它们添加它们需要的任何路径.

在我的app/server.coffeecoffeescript文件中,我做:

[
  'api'
  'authorization'
  'authentication'
  'domains'
  'users'
  'stylesheets'
  'javascripts'
  'tests'
  'sales'
].map (controllerName) ->
  controller = require './controllers/' + controllerName
  controller.setup app
Run Code Online (Sandbox Code Playgroud)

所以我有这样的文件:

app/controllers/api.coffee
app/controllers/authorization.coffee
app/controllers/authentication.coffee
app/controllers/domains.coffee
Run Code Online (Sandbox Code Playgroud)

例如在我的域控制器中,我有这样的setup功能.

exports.setup = (app) ->
  controller = new exports.DomainController
  route = '/domains'
  app.post route, controller.create
  app.put route, api.needId
  app.delete route, api.needId
  route = '/domains/:id'
  app.put route, controller.loadDomain, controller.update
  app.del route, controller.loadDomain, exports.delete
  app.get route, controller.loadDomain, (req, res) ->
    res.sendJSON req.domain, status.OK
Run Code Online (Sandbox Code Playgroud)

查看

提出意见app/views正在成为习惯的地方.我把它像这样摆好.

app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade
Run Code Online (Sandbox Code Playgroud)

静态文件

进入一个public子目录.

Github上/ Semver/NPM

在您的git repo root上放置一个README.md markdown文件,用于github.

将一个带有语义版本号的package.json文件放在你的git repo root中,用于NPM.

  • 咖啡脚本让人难以理解:/任何获得香草JS编辑的机会?谢谢 (74认同)
  • 这个repo有很多模式你可以用作参考:https://github.com/focusaurus/peterlyons.com (4认同)

dth*_*ree 52

以下是Peter Lyons的回答,按照其他几个人的要求,从Coffeescript移植到香草JS.彼得的答案很有能力,任何对我的答案投票的人都应该投票给他.


配置

你做的很好.我喜欢在具有config.js嵌套命名空间的顶级文件中设置我自己的config命名空间.

// Set the current environment to true in the env object
var currentEnv = process.env.NODE_ENV || 'development';
exports.appName = "MyApp";
exports.env = {
  production: false,
  staging: false,
  test: false,
  development: false
};  
exports.env[currentEnv] = true;
exports.log = {
  path: __dirname + "/var/log/app_#{currentEnv}.log"
};  
exports.server = {
  port: 9600,
  // In staging and production, listen loopback. nginx listens on the network.
  ip: '127.0.0.1'
};  
if (currentEnv != 'production' && currentEnv != 'staging') {
  exports.enableTests = true;
  // Listen on all IPs in dev/test (for testing from other machines)
  exports.server.ip = '0.0.0.0';
};
exports.db {
  URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"
};
Run Code Online (Sandbox Code Playgroud)

这对系统管理员编辑很友好.然后当我需要某些东西时,比如数据库连接信息,它就是

require('./config').db.URL
Run Code Online (Sandbox Code Playgroud)

路线/控制器

我喜欢将我的路由留给我的控制器并将它们组织在一个app/controllers子目录中.然后我可以加载它们并让它们添加它们需要的任何路径.

在我的app/server.jsjavascript文件中,我做:

[
  'api',
  'authorization',
  'authentication',
  'domains',
  'users',
  'stylesheets',
  'javascripts',
  'tests',
  'sales'
].map(function(controllerName){
  var controller = require('./controllers/' + controllerName);
  controller.setup(app);
});
Run Code Online (Sandbox Code Playgroud)

所以我有这样的文件:

app/controllers/api.js
app/controllers/authorization.js
app/controllers/authentication.js
app/controllers/domains.js
Run Code Online (Sandbox Code Playgroud)

例如在我的域控制器中,我有这样的setup功能.

exports.setup = function(app) {
  var controller = new exports.DomainController();
  var route = '/domains';
  app.post(route, controller.create);
  app.put(route, api.needId);
  app.delete(route, api.needId);
  route = '/domains/:id';
  app.put(route, controller.loadDomain, controller.update);
  app.del(route, controller.loadDomain, function(req, res){
    res.sendJSON(req.domain, status.OK);
  });
}
Run Code Online (Sandbox Code Playgroud)

查看

提出意见app/views正在成为习惯的地方.我把它像这样摆好.

app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade
Run Code Online (Sandbox Code Playgroud)

静态文件

进入一个public子目录.

Github上/ Semver/NPM

在您的git repo root上放置一个README.md markdown文件,用于github.

将一个带有语义版本号的package.json文件放在你的git repo root中,用于NPM.


San*_*nda 42

我的问题是在2011年4月推出的,它很安静.在此期间,我可以改善使用Express.js的体验以及如何构建使用此库编写的应用程序.所以,我在这里分享我的经验.

这是我的目录结构:

??? app.js   // main entry
??? config   // The configuration of my applications (logger, global config, ...)
??? models   // The model data (e.g. Mongoose model)
??? public   // The public directory (client-side code)
??? routes   // The route definitions and implementations
??? services // The standalone services (Database service, Email service, ...)
??? views    // The view rendered by the server to the client (e.g. Jade, EJS, ...)
Run Code Online (Sandbox Code Playgroud)

App.js

app.js文件的目标是引导expressjs应用程序.它加载配置模块,记录器模块,等待数据库连接,...,并运行快速服务器.

'use strict';
require('./config');
var database = require('./services/database');
var express = require('express');
var app = express();
module.exports = app;

function main() {
  var http = require('http');

  // Configure the application.
  app.configure(function () {
    // ... ... ...
  });
  app.configure('production', function () {
    // ... ... ...
  });
  app.configure('development', function () {
    // ... ... ...
  });

  var server = http.createServer(app);

  // Load all routes.
  require('./routes')(app);

  // Listen on http port.
  server.listen(3000);
}

database.connect(function (err) {
  if (err) { 
    // ...
  }
  main();
});
Run Code Online (Sandbox Code Playgroud)

路线/

routes目录有一个index.js文件.它的目标是引入一种魔法来加载routes/目录中的所有其他文件.这是实施:

/**
 * This module loads dynamically all routes modules located in the routes/
 * directory.
 */
'use strict';
var fs = require('fs');
var path = require('path');

module.exports = function (app) {
  fs.readdirSync('./routes').forEach(function (file) {
    // Avoid to read this current file.
    if (file === path.basename(__filename)) { return; }

    // Load the route file.
    require('./' + file)(app);
  });
};
Run Code Online (Sandbox Code Playgroud)

使用该模块,创建新的路由定义和实现非常简单.例如,hello.js:

function hello(req, res) {
  res.send('Hello world');
}

module.exports = function (app) {
  app.get('/api/hello_world', hello);
};
Run Code Online (Sandbox Code Playgroud)

每个路由模块都是独立的.

  • 加一个用于独立服务。许多布局建议都缺少很多内容。 (2认同)

小智 18

我喜欢使用全局"app",而不是导出函数等

  • 我认为TJ为我们提供了大量代码;) (5认同)

nee*_*ebz 17

我认为这是一个很好的方式.不仅限于表达,但我在github上看到了很多相同的node.js项目.它们取出配置参数+较小的模块(在某些情况下,每个URI)都被分解在单独的文件中.

我建议在github上通过特定于快递的项目来获得一个想法.IMO你的方式是正确的.


Sim*_*kir 15

它现在是2015年底,经过3年的开发和小型和大型项目.结论?

不要做一个大的MVC,而是将它分成模块

所以...

为什么?

  • 通常可以在一个模块(例如产品)上工作,您可以单独更改.

  • 您可以重用模块

  • 你可以分别测试它

  • 你可以分开更换它

  • 它们具有清晰(稳定)的接口

    - 最新的,如果有多个开发人员在工作,模块分离会有所帮助

nodebootstrap项目也有类似的做法,以我的最终结构.(github)

这个结构怎么样?

  1. 小型封装模块,每个模块都有独立的MVC

  2. 每个模块都有一个package.json

  3. 作为结构的一部分进行测试(在每个模块中)

  4. 全局配置,库和服务

  5. 集成Docker,集群,永远

Folderoverview(参见模块的lib文件夹):

nodebootstrap结构

  • 如果您还可以使用扩展的各个模块来更新文件夹概述图片,这将对您有所帮助,例如,如何构造它们的示例。 (3认同)

ecd*_*per 7

我不认为将路由添加到配置是一个好方法.更好的结构可能是这样的:

application/
| - app.js
| - config.js
| - public/ (assets - js, css, images)
| - views/ (all your views files)
| - libraries/ (you can also call it modules/ or routes/)
    | - users.js
    | - products.js
    | - etc...
Run Code Online (Sandbox Code Playgroud)

所以products.js和users.js将包含你所有逻辑内的所有路由.


Ste*_*fan 7

自问题的最后一个答案以来已经有一段时间了,Express最近还发布了第4版,它为组织应用程序结构添加了一些有用的东西.

以下是关于如何构建Express应用程序的最佳实践的最新博客文章. http://www.terlici.com/2014/08/25/best-practices-express-structure.html

还有一个GitHub存储库应用了本文中的建议.它始终与最新的Express版本保持同步.
https://github.com/terlici/base-express


Raj*_*lam 7

我给MVC风格的文件夹结构请找下面.

我们在大中型Web应用程序中使用了bellow文件夹结构.

 myapp   
|
|
|____app
|      |____controllers
|      |    |____home.js
|      |
|      |____models
|      |     |___home.js
|      |
|      |____views
|           |___404.ejs
|           |___error.ejs
|           |___index.ejs
|           |___login.ejs
|           |___signup.ejs
|   
|
|_____config
|     |___auth.js
|     |___constants.js
|     |___database.js
|     |___passport.js
|     |___routes.js
|
|
|____lib
|    |___email.js
|
|____node_modules
|
|
|____public.js
|    |____css
|    |    |__style.css
|    |    
|    |____js
|    |    |__script.js
|    |
|    |____img
|    |    |__img.jpg
|    |
|    |
|    |____uploads
|         |__img.jpg
|      
|   
|
|_____app.js
|
|
|
|_____package.json
Run Code Online (Sandbox Code Playgroud)

我为Generation express mvc文件夹结构创建了一个npm模块.

请找到下面的 https://www.npmjs.com/package/express-mvc-generator

只需简单的步骤即可生成和使用此模块.

i)安装模块 npm install express-mvc-generator -g

ii)检查选项 express -h

iii)生成明确的mvc结构 express myapp

iv)安装依赖项npm install:

v)打开你的config/database.js,请配置你的mongo db.

vi)运行应用程序node appnodemon app

vii)检查URL http:// localhost:8042/signuphttp:// yourip:8042/signup


Tia*_*HUo 6

好吧,我将我的路由作为json文件,我在开头读取,并在app.js中的for循环中设置路由.route.json包括应该调用的视图,以及将发送到路由的值的键.
这适用于许多简单的情况,但我必须为特殊情况手动创建一些路由.


Ren*_*ama 6

我已经写了一篇关于此事的文章.它基本上使用了一个routeRegistrar迭代文件夹中/controllers调用其函数的文件init.函数init将express app变量作为参数,以便您可以按照自己的方式注册路径.

var fs = require("fs");
var express = require("express");
var app = express();

var controllersFolderPath = __dirname + "/controllers/";
fs.readdirSync(controllersFolderPath).forEach(function(controllerName){
    if(controllerName.indexOf("Controller.js") !== -1){
        var controller = require(controllersFolderPath + controllerName);
        controller.init(app);
    }
});

app.listen(3000);
Run Code Online (Sandbox Code Playgroud)


Uly*_*s V 5

这可能是有趣的:

https://github.com/flatiron/nconf

具有文件,环境变量,命令行参数和原子对象合并的分层node.js配置.


Ben*_*due 5

http://locomotivejs.org/提供了一种构建使用 Node.js 和 Express 构建的应用程序的方法。

来自网站:

“Locomotive 是 Node.js 的 Web 框架。Locomotive 支持 MVC 模式、RESTful 路由和约定优于配置,同时与任何数据库和模板引擎无缝集成。Locomotive 基于 Express 构建,保留了您所期望的强大功能和简单性来自节点。”