我正在使用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)?

谢谢你的建议!


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

我建议你浏览一下github上的express-specific项目。在我看来,你的做法是正确的。


我把我的路由作为一个json文件,我在一开始读的,然后在app。js的for循环中设置路由。的路线。Json包含应该被调用的视图,以及将被发送到路由中的值的键。 这适用于许多简单的情况,但我必须手动为特殊情况创建一些路由。


我喜欢使用全局“应用程序”,而不是导出一个函数等


更新(2013-10-29):请参阅我的另一个答案,它有JavaScript而不是CoffeeScript的流行需求,以及一个样板github回购和一个广泛的自述me详细介绍了我对这个主题的最新建议。

配置

你做的很好。我喜欢在顶级配置中设置自己的配置名称空间。Coffee文件,具有这样的嵌套名称空间。

#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}"

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

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

公路/加强一

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

在我的应用程序/服务器。我做的是:

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

我有这样的文件:

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

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

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

的观点

在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根目录中有一个语义版本号。


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

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会包含所有的路由和逻辑。


你可能会感兴趣:

https://github.com/flatiron/nconf

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


我已经写了一篇关于这件事的文章。它基本上利用了一个routeRegistrar来迭代文件夹/控制器中的文件,调用它的函数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);

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根目录中有一个语义版本号。


好吧,已经有一段时间了,这是一个很受欢迎的问题,所以我已经向前走了,用JavaScript代码创建了一个脚手架github存储库和一个关于我如何构造一个中型express.js应用程序的长README。

Focusaurus /express_code_structure是带有最新代码的repo。欢迎拉请求。

下面是README的快照,因为stackoverflow不喜欢只有链接的答案。我会做一些更新,因为这是一个新的项目,我将继续更新,但最终github回购将是这个信息的最新地方。


#快速代码结构

这个项目是一个如何组织一个中型express.js web应用程序的例子。

目前至少到2016年12月14日express v4.14

你的应用程序有多大?

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

如果您的应用程序很小,就不需要像这里所示的这样深的目录结构。只要保持简单,在存储库的根目录中插入一些.js文件就可以了。瞧。

If your application is huge, at some point you need to break it up into distinct npm packages. In general the node.js approach seems to favor many small packages, at least for libraries, and you should build your application up by using several npm packages as that starts to make sense and justify the overhead. So as your application grows and some portion of the code becomes clearly reusable outside of your application or is a clear subsystem, move it to its own git repository and make it into a standalone npm package.

因此,本项目的重点是说明一个中型应用程序的可行结构。

你的整体架构是什么

构建web应用程序有许多方法,例如

服务器端MVC,一种Ruby on Rails 单页应用样式MongoDB/Express/Angular/Node (MEAN) 基本的网站与一些形式 模型/操作/视图/事件风格的MVC已经死了,是时候继续前进了 还有很多现在和历史上的

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

该网站有一些传统的静态页面/模板 网站的“应用程序”部分是按单页应用程序样式开发的 应用程序向浏览器公开REST/JSON样式的API 该应用程序模拟了一个简单的业务领域,在本例中,它是一个汽车经销商应用程序

那么Ruby on Rails呢?

这个项目贯穿始终的一个主题是,Ruby on Rails中所体现的许多思想以及它们所采用的“约定优于配置”的决策,虽然被广泛接受和使用,但实际上并没有多大帮助,有时还与这个存储库所推荐的相反。

我在这里的主要观点是,有组织代码的基本原则,并且基于这些原则,Ruby on Rails约定对Ruby on Rails社区(主要)是有意义的。然而,只是不加思索地模仿这些惯例并没有抓住重点。一旦你掌握了基本的原则,你所有的项目都将被很好地组织和清晰:shell脚本,游戏,移动应用程序,企业项目,甚至你的主目录。

For the Rails community, they want to be able to have a single Rails developer switch from app to app to app and be familiar and comfortable with it each time. This makes great sense if you are 37 signals or Pivotal Labs, and has benefits. In the server-side JavaScript world, the overall ethos is just way more wild west anything goes and we don't really have a problem with that. That's how we roll. We're used to it. Even within express.js, it's a close kin of Sinatra, not Rails, and taking conventions from Rails is usually not helping anything. I'd even say Principles over Convention over Configuration.

基本原则和动机

Be mentally manageable The brain can only deal with and think about a small number of related things at once. That's why we use directories. It helps us deal with complexity by focusing on small portions. Be size-appropriate Don't create "Mansion Directories" where there's just 1 file all alone 3 directories down. You can see this happening in the Ansible Best Practices that shames small projects into creating 10+ directories to hold 10+ files when 1 directory with 3 files would be much more appropriate. You don't drive a bus to work (unless you're a bus driver, but even then your driving a bus AT work not TO work), so don't create filesystem structures that aren't justified by the actual files inside them. Be modular but pragmatic The node community overall favors small modules. Anything that can cleanly be separated out from your app entirely should be extracted into a module either for internal use or publicly published on npm. However, for the medium-sized applications that are the scope here, the overhead of this can add tedium to your workflow without commensurate value. So for the time when you have some code that is factored out but not enough to justify a completely separate npm module, just consider it a "proto-module" with the expectation that when it crosses some size threshold, it would be extracted out. Some folks such as @hij1nx even include an app/node_modules directory and have package.json files in the proto-module directories to facilitate that transition and act as a reminder. Be easy to locate code Given a feature to build or a bug to fix, our goal is that a developer has no struggle locating the source files involved. Names are meaningful and accurate crufty code is fully removed, not left around in an orphan file or just commented out Be search-friendly all first-party source code is in the app directory so you can cd there are run find/grep/xargs/ag/ack/etc and not be distracted by third party matches Use simple and obvious naming npm now seems to require all-lowercase package names. I find this mostly terrible but I must follow the herd, thus filenames should use kebab-case even though the variable name for that in JavaScript must be camelCase because - is a minus sign in JavaScript. variable name matches the basename of the module path, but with kebab-case transformed to camelCase Group by Coupling, Not by Function This is a major departure from the Ruby on Rails convention of app/views, app/controllers, app/models, etc Features get added to a full stack, so I want to focus on a full stack of files that are relevant to my feature. When I'm adding a telephone number field to the user model, I don't care about any controller other than the user controller, and I don't care about any model other than the user model. So instead of editing 6 files that are each in their own directory and ignoring tons of other files in those directories, this repository is organized such that all the files I need to build a feature are colocated By the nature of MVC, the user view is coupled to the user controller which is coupled to the user model. So when I change the user model, those 3 files will often change together, but the deals controller or customer controller are decoupled and thus not involved. Same applies to non-MVC designs usually as well. MVC or MOVE style decoupling in terms of which code goes in which module is still encouraged, but spreading the MVC files out into sibling directories is just annoying. Thus each of my routes files has the portion of the routes it owns. A rails-style routes.rb file is handy if you want an overview of all routes in the app, but when actually building features and fixing bugs, you only care about the routes relevant to the piece you are changing. Store tests next to the code This is just an instance of "group by coupling", but I wanted to call it out specifically. I've written many projects where the tests live under a parallel filesystem called "tests" and now that I've started putting my tests in the same directory as their corresponding code, I'm never going back. This is more modular and much easier to work with in text editors and alleviates a lot of the "../../.." path nonsense. If you are in doubt, try it on a few projects and decide for yourself. I'm not going to do anything beyond this to convince you that it's better. Reduce cross-cutting coupling with Events It's easy to think "OK, whenever a new Deal is created, I want to send an email to all the Salespeople", and then just put the code to send those emails in the route that creates deals. However, this coupling will eventually turn your app into a giant ball of mud. Instead, the DealModel should just fire a "create" event and be entirely unaware of what else the system might do in response to that. When you code this way, it becomes much more possible to put all the user related code into app/users because there's not a rat's nest of coupled business logic all over the place polluting the purity of the user code base. Code flow is followable Don't do magic things. Don't autoload files from magic directories in the filesystem. Don't be Rails. The app starts at app/server.js:1 and you can see everything it loads and executes by following the code. Don't make DSLs for your routes. Don't do silly metaprogramming when it is not called for. If your app is so big that doing magicRESTRouter.route(somecontroller, {except: 'POST'}) is a big win for you over 3 basic app.get, app.put, app.del, calls, you're probably building a monolithic app that is too big to effectively work on. Get fancy for BIG wins, not for converting 3 simple lines to 1 complex line. Use lower-kebab-case filenames This format avoids filesystem case sensitivity issues across platforms npm forbids uppercase in new package names, and this works well with that

express.js细节

Don't use app.configure. It's almost entirely useless and you just don't need it. It is in lots of boilerplate due to mindless copypasta. THE ORDER OF MIDDLEWARE AND ROUTES IN EXPRESS MATTERS!!! Almost every routing problem I see on stackoverflow is out-of-order express middleware In general, you want your routes decoupled and not relying on order that much Don't use app.use for your entire application if you really only need that middleware for 2 routes (I'm looking at you, body-parser) Make sure when all is said and done you have EXACTLY this order: Any super-important application-wide middleware All your routes and assorted route middlewares THEN error handlers Sadly, being sinatra-inspired, express.js mostly assumes all your routes will be in server.js and it will be clear how they are ordered. For a medium-sized application, breaking things out into separate routes modules is nice, but it does introduce peril of out-of-order middleware

应用程序符号链接技巧

在Node.js的Better local require()路径中,社区详细地概述和讨论了许多方法。我可能很快就会决定选择“只是处理大量的../../../..”或者使用requireFrom模块。然而,目前,我一直在使用下面详细介绍的符号链接技巧。

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

create a symlink under node_modules for your app cd node_modules && ln -nsf ../app add just the node_modules/app symlink itself, not the entire node_modules folder, to git git add -f node_modules/app Yes, you should still have "node_modules" in your .gitignore file No, you should not put "node_modules" into your git repository. Some people will recommend you do this. They are incorrect. Now you can require intra-project modules using this prefix var config = require("app/config"); var DealModel = require("app/deals/deal-model"); Basically, this makes intra-project requires work very similarly to requires for external npm modules. Sorry, Windows users, you need to stick with parent directory relative paths.

配置

一般来说,代码模块和类只需要传入一个基本的JavaScript选项对象。只有app/server.js应该加载app/config.js模块。在此基础上,它可以根据需要合成小的选项对象来配置子系统,但是将每个子系统耦合到一个充满额外信息的大型全局配置模块是糟糕的耦合。

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

NODE_ENV

这是另一个从Rails继承而来的诱人但糟糕的想法。app/config.js中应该有1个地方查看NODE_ENV环境变量。其他所有内容都应采用显式选项作为类构造函数参数或模块配置参数。

如果电子邮件模块有一个关于如何发送电子邮件的选项(SMTP,登录到stdout,放入队列等),它应该采用一个像{deliver: 'stdout'}这样的选项,但它绝对不应该检查NODE_ENV。

测试

我现在将测试文件与其对应的代码放在同一个目录中,并使用文件名扩展名命名约定来区分测试和生产代码。

foo.js有模块"foo"的代码 foo.tape.js有针对foo的基于节点的测试,并且位于相同的目录中 Foo.btape.js可用于需要在浏览器环境中执行的测试

我使用文件系统glob和find。-name '*.tape.js'命令来访问我的所有测试。

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

这个项目的作用域主要是关于文件和目录的位置,我不想添加太多其他作用域,但我只想提到,我将代码组织成3个不同的部分。

CommonJS的打开块需要调用状态依赖项 纯javascript的主要代码块。这里没有CommonJS污染。不要引用导出、模块或require。 CommonJS设置导出的关闭块


我的问题是在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);
};

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


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

来自网站:

“Locomotive是一个Node.js的web框架。机车支持MVC 模式、RESTful路由和约定优于配置,而 与任何数据库和模板引擎无缝集成。 机车建立在快车,保留权力和简单 你对Node的期望。”


距离上次回答这个问题已经有一段时间了,Express最近也发布了第4版,它增加了一些有用的东西来组织应用程序结构。

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

还有一个GitHub存储库应用了本文中的建议。它总是最新的快车版本。 https://github.com/terlici/base-express


这是我的大多数express项目目录结构的外观。

我通常使用express dirname来初始化项目,请原谅我的懒惰,但它非常灵活和可扩展。PS -你需要为此获取express-generator(对于那些正在寻找它的人来说,sudo npm install -g express-generator, sudo因为你正在全局安装它)

|-- bin
    |-- www //what we start with "forever"
|-- bower_components
|-- models
    |-- database.js
    |-- model1.js //not this exact name ofcourse.
    |-- .
|-- node_modules
|-- public
    |-- images
    |-- javascripts
        |-- controllers
        |-- directives
        |-- services
        |-- app.js
        |-- init.js //contains config and used for initializing everything, I work with angular a lot.
    |-- stylesheets
|-- routes
    |-- some
    |-- hierarchy
    .
    .
|-- views
    |-- partials
    |-- content
|-- .env
|-- .env.template
|-- app.js
|-- README.md

你一定想知道为什么是。env文件?因为他们工作!我在我的项目中使用了dotenv模块(最近很多),而且它很有效!在app.js或www中弹出这两个语句

var dotenv = require('dotenv');
dotenv.config({path: path.join(__dirname + "/.env")});

另一行用于快速设置/bower_components以在资源/ext下提供静态内容

app.use('/ext', express.static(path.join(__dirname, 'bower_components')));

它可能适合那些希望同时使用Express和Angular的人,或者只需要表达而不需要javascript层次结构的人。


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

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

所以…

Why?

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

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

这个结构是什么样的?

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

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


我最近把模块当成了独立的小应用。

|-- src
  |--module1
  |--module2
     |--www
       |--img
       |--js
       |--css
     |--#.js
     |--index.ejs
  |--module3
  |--www
     |--bower_components
     |--img
     |--js
     |--css
  |--#.js
  |--header.ejs
  |--index.ejs
  |--footer.ejs

现在对于任何模块路由(#.js),视图(*.ejs), js, css和资产都是相邻的。 子模块路由设置在父文件#.js中,有另外两行

router.use('/module2', opt_middleware_check, require('./module2/#'));
router.use(express.static(path.join(__dirname, 'www')));

这样甚至子模块也是可能的。

不要忘记将view设置为src目录

app.set('views', path.join(__dirname, 'src'));

我给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


我的结构快车4。 https://github.com/odirleiborgert/borgert-express-boilerplate

View engine: twig
Security: helmet
Flash: express-flash
Session: express-session
Encrypt: bcryptjs
Modules: express-load
Database: MongoDB
    ORM: Mongoose
    Mongoose Paginate
    Mongoose Validator
Logs: winston + winston-daily-rotate-file
Nodemon
CSS: stylus
Eslint + Husky

结构

|-- app
    |-- controllers
    |-- helpers
    |-- middlewares
    |-- models
    |-- routes
    |-- services
|-- bin
|-- logs
|-- node_modules
|-- public
    |-- components
    |-- images
    |-- javascripts
    |-- stylesheets
|-- views
|-- .env
|-- .env-example
|-- app.js
|-- README.md

一个简单的方法来结构你的express应用程序:

在main index.js中应该保持以下顺序。 所有app.set都应该放在第一位。 所有app.use都应该排在第二位。 然后是其他api及其函数或其他文件中的route-continue 简单的 app.use(“/密码”,passwordApi); app.use(“/ user”,userApi); app.post(“/令牌”,passport.createToken); app.post(“/注销”,passport.logout)


使用handlebar和Passportjs的ExpressJs项目MVC结构的最佳方法

- app
      -config 
        -passport-setup.js
      -controllers
      -middleware
      -models
      -routes
      -service
    -bin
      -www
      -configuration.js
      -passport.js
    -node_modules
    -views
     -handlebars page
    -env
    -.gitignore
    -package.json
    -package-lock.json

js结构看起来很好,干净给我,所以我使用MVC风格的结构为我的表达项目,类似于帆。js。

project_root  
|  
|_ _ app  
|_ _ |_ _ controllers  
|_ _ |_ _ |_ _ UserController.js  
|_ _ |_ _ middlewares  
|_ _ |_ _ |_ _ error.js  
|_ _ |_ _ |_ _ logger.js  
|_ _ |_ _ models  
|_ _ |_ _ |_ _ User.js  
|_ _ |_ _ services  
|_ _ |_ _ |_ _ DatabaseService.js  
|  
|_ _ config  
|_ _ |_ _ constants.js  
|_ _ |_ _ index.js  
|_ _ |_ _ routes.js  
|  
|_ _ public  
|_ _ |_ _ css  
|_ _ |_ _ images  
|_ _ |_ _ js  
|  
|_ _ views  
|_ _ |_ _ user  
|_ _ |_ _ |_ _ index.ejs  

应用程序文件夹-包含应用程序的整体登录。 Config文件夹-包含应用程序配置,常量,路由。 公共文件夹-包含样式,图像,脚本等。 Views文件夹——包含每个模型的视图(如果有的话)

样板项目可以在这里找到, https://github.com/abdulmoiz251/node-express-rest-api-boilerplate