33

我正在使用 Node 和 Express 创建一个应用程序。但是,我可以看到管理放置在内部的所有路由很快就会变得困难app.js。我已将所有模型放在一个子目录/models中。

这是我的应用程序当前结构:

app.js
models
  -- products
  -- customers
  -- ...
public
views
node_modules

app.js

var express = require('express'),
    routes = require('./routes'),
    user = require('./routes/user'),
    http = require('http'),
    path = require('path'),
    EmployeeProvider = require('./models/employeeprovider').EmployeeProvider,
    Products = require('./models/products').Products,
    Orders = require('./models/orders').Orders,
    Customers = require('./models/customers').Customers,
    checkAuth = function(req, res, next) {
      if (!req.session.user_id) {
        res.send('You are not authorized to view this page');
      } else {
        next();
      }
    };

var app = express();

然后是一些配置port,如views目录、渲染引擎等。

再往下,app.js我有路线:

app.get('/product/edit', auth, function(req, res) {
  Products.findAll(function(error, prds) {
    res.render('product_edit', {
      title: 'New Product',
      products: prds
    });
  });
});

在顶部,我将内容分配models/products.js给一个变量,一切正常。但是,将所有路线保留在内部app.js并不理想。但是,如果我将路线移动到routes/product.js并加载Products模型:

var prod = require('../models/products.js');

我收到一条错误消息,说 object has no method findAll

我究竟做错了什么?如何从中删除路线app.js

4

3 回答 3

33

从 express 4.xRouter开始添加以支持您的情况。

路由器对象是中间件和路由的隔离实例。您可以将其视为“迷你应用程序”,仅能够执行中间件和路由功能。每个 Express 应用程序都有一个内置的应用程序路由器。

来自expressjs 网站的示例:

// routes/calendarRouter.js

var express  = require('express');
var router = express.Router();

// invoked for any requested passed to this router
router.use(function(req, res, next) {
  // .. some logic here .. like any other middleware
  next();
});

// will handle any request that ends in /events
// depends on where the router is "use()'d"
router.get('/events', function(req, res, next) {
  // ..
});

module.exports = router;

然后在 app.js 中:

// skipping part that sets up app

var calendarRouter = require('./routes/calendarRouter');

// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', calendarRouter);

// rest of logic
于 2014-04-15T07:49:43.023 回答
33

由于我不喜欢重复,这就是我所做的:

// app.js
//...
var routes = requireDir('./routes'); // https://www.npmjs.org/package/require-dir
for (var i in routes) app.use('/', routes[i]);
//...

路线中的每个文件都像:

// routes/someroute.js
var express  = require('express');
var router   = express.Router();

router.get('/someroute', function(req, res) {
    res.render('someview', {});
});

module.exports = router;

这样您就可以避免像这样的冗长重复列表:

app.use('/'           , require('./routes/index'));
app.use('/repetition' , require('./routes/repetition'));
app.use('/is'         , require('./routes/is'));
app.use('/so'         , require('./routes/so'));
app.use('/damn'       , require('./routes/damn'));
app.use('/boring'     , require('./routes/boring'));

编辑:这些长示例假设每个路由文件都包含以下内容:

var router = express.Router();
router.get('/', function(req, res, next) {
    // ...
    next();
});
module.exports = router;

它们都可以挂载到“root”,但对于它们来说,“root”实际上是给定的特定路径app.use,因为您可以将路由挂载到特定路径(这也支持使用正则表达式指定路径,Express关于路由可以做的事情非常简洁)。

于 2014-08-22T11:42:13.490 回答
21

我可以向您推荐这个文件结构(根据tjholowaychuk 中使用 Node.js 和 Express 的模块化 Web 应用程序):

app.js
   modules
      users
         index.js
         model.js
      users-api
         index.js
      static-pages
         index.js

user-apistatic-pages导出 expressjs 应用程序,您可以轻松地将它们挂载到 app.js 中。在users模块中,您可以描述一些数据访问操作和有关操作用户实体的所有方法(如创建、更新等)。我们的 API 模块将使用所有这些方法。

这是 app.js 文件的示例代码(没有常见的 express 内容,仅安装来自不同模块的路由):

var express = require('express');
var app = express();

// mount all the applications
app.use('/api/v1', require("user-api"));
app.use(require("static-pages"));

app.listen(3000);

要以这种方式使用您的模块,您必须像这样启动您的应用程序NODE_PATH=modules node app.js(我将此行放在脚本部分的 package.json 文件中)。

这是users模块的示例代码:

index.js

User = require("./model");

module.exports = {
    get: function(id, callback) {
        User.findOne(id, function(err, user) {
           callback(err, user);
        });
    },
    create: function(data, callback) {
        // do whatever with incoming data here
        data = modifyDataInSomeWay(data);
        var newUser = new User(data);
        newUser.save(function(err, savedUser) {
            // some logic here
            callback(err, savedUser); 
        });
    }
};

model.js(当然是 Mongoose 的例子!)

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var User = new Schema({
    firstname   : {type: String, required: false},
    lastname    : {type: String, required: false},
    email       : {type: String, required: true}
});

module.exports = mongoose.model('user', User);

user-api模块的例子(这里是关于分离路线和模型的答案的主要部分)。

var users = require("users");

var express = require("express");
var app = module.exports = express(); // we export new express app here!

app.post('/users', function(req, res, next) {
    // try to use high-level calls here
    // if you want something complex just create another special module for this
    users.create(req.body, function(err, user) {
        if(err) return next(err); // do something on error
        res.json(user); // return user json if ok
    });
});

和 的例子static-pages。如果您不打算构建一种 REST 接口,您可以简单地创建几个仅呈现页面的模块。

var express = require("express");
var app = module.exports = express(); // we export new express app here again!

app.get('/', function(req, res, next) {
    res.render('index', {user: req.user});
});

app.get('/about', function(req, res, next) {
    // get data somewhere and put it in the template
    res.render('about', {data: data});
});

当然,你可以用模块做任何你想做的事情。expressjs 的主要思想是使用许多小应用程序而不是单个应用程序。

关于 nodejs 模块,您可以阅读stackoverflowdocs

希望这可以帮助。

于 2013-10-28T07:20:22.727 回答