我正在使用NodeJS的ExpressJS web框架。

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

我想要这样的目录结构:

| my-application
| -- app.js
| -- config/
     | -- environment.js
     | -- routes.js

这是我的代码:

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

配置/ 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());
    });
};

配置/ routes.js

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

我的代码工作得很好,我认为目录的结构很漂亮。然而,代码必须进行调整,我不确定它是否好/漂亮。

是更好地使用我的目录结构和调整代码或简单地使用一个文件(app.js)?

谢谢你的建议!


当前回答

我的问题是在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, ...)

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

路线/

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

使用该模块,创建一个新的路由定义和实现非常容易。例如,hello.js:

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

module.exports = function (app) {
  app.get('/api/hello_world', hello);
};

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

其他回答

我不认为在配置中添加路由是一个好方法。一个更好的结构可以是这样的:

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...

products。js和users。js会包含所有的路由和逻辑。

我给MVC风格的文件夹结构,请找到下面。

我们在大型和中型web应用程序中使用了波纹文件夹结构。

 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

我已经为生成express mvc文件夹结构器创建了一个npm模块。

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

只需简单的步骤来生成和使用这个模块。

I)安装模块NPM

Ii)检查选项express -h

iii)生成express mvc结构express myapp

iv)安装依赖项:

v)打开config/database.js, Please configure your mongo db。

vi)运行应用节点app或nodemon app

vii)查看网址http://localhost:8042/signup或http://yourip:8042/signup

现在是2015年底,在开发我的结构3年之后,在小型和大型项目中。结论?

不做一个大的MVC,而是在模块中分离

所以…

Why?

通常一个人在一个模块上工作(例如产品),你可以独立地更改它。 您可以重用模块 你可以单独测试它 你可以单独替换它 它们有清晰(稳定)的接口 -至少,如果有多个开发人员工作,模块分离是有帮助的

nodebootstrap项目的方法与我的最终结构类似。(github)

这个结构是什么样的?

小型封装模块,每个模块都有独立的MVC 每个模块都有一个package.json 测试作为结构的一部分(在每个模块中) 全局配置、库和服务 集成Docker,集群,永远

文件夹概述(参见lib文件夹中的模块):

1)你的Express项目文件系统可能是这样的:

/ ...
/lib
/node_modules
/public
/views
      app.js
      config.json
      package.json

app.js -你的全局应用容器

2)模块主文件(lib/mymodule/index.js):

var express = require('express');    
var app = module.exports = express();
// and load module dependencies ...  

// this place to set module settings
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');

// then do module staff    
app.get('/mymodule/route/',function(req,res){ res.send('module works!') });

3)在main app.js中连接模块

...
var mymodule = require('mymodule');
app.use(mymodule);

4)样本逻辑

lib/login
lib/db
lib/config
lib/users
lib/verify
lib/
   /api/ 
   ...
lib/
   /admin/
      /users/
      /settings/
      /groups/
...

最适合测试 最适合规模 分开取决于模块 按功能(或模块)分组路由

tj说/在Vimeo上展示有趣的想法如何模块化表达应用程序- 使用Node.js和Express的模块化web应用程序。强大而简单。

以下是Peter Lyons的回答,根据其他人的要求,从Coffeescript移植到vanilla JS。彼得的回答很有能力,对我的答案投票的人也应该对他的答案投票。


配置

你做的很好。我喜欢在顶级的config.js文件中设置自己的配置名称空间,其中包含这样一个嵌套的名称空间。

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

这对于系统管理员编辑是友好的。然后当我需要一些东西时,比如DB连接信息,它

require('./config').db.URL

公路/加强一

我喜欢把我的路径留给我的控制器,并在app/controllers子目录中组织它们。然后我可以加载他们,让他们添加任何他们需要的路线。

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

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

我有这样的文件:

app/controllers/api.js
app/controllers/authorization.js
app/controllers/authentication.js
app/controllers/domains.js

例如在域控制器中,我有一个这样的设置函数。

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

的观点

在app/views中放置视图已经成为一种习惯。我是这样写的。

app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade

静态文件

进入一个公共子目录。

Github/Semver/NPM

放一个自述文件。Md markdown文件在你的git回购根github。

放一个包裹。json文件,在你的NPM的git repo根目录中有一个语义版本号。