如何使用 NodeJS 和 Express 从 app.js 中分离路由和模型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19619936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:06:02  来源:igfitidea点击:

How to separate the routes and models from app.js using NodeJS and Express

node.jsexpress

提问by WagnerMatosUK

I'm creating an app using Node and Express. However, I can see it'll soon become difficult to manage all the routes that are placed inside app.js. I have placed all my models in a subdirectory /models.

我正在使用 Node 和 Express 创建一个应用程序。但是,我可以看到,管理放置在app.js. 我已将所有模型放在一个子目录中/models

Here's my app current structure:

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

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

In app.js:

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

Then some configuration like port, viewsdirectory, rendering engine, etc.

然后一些配置一样portviews目录,渲染引擎等。

Further down app.jsI've got the routes:

再往下app.js我有路线:

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

At the top I'm assigning the contents of models/products.jsto a variable, all works fine. However keeping all routes inside app.jsis not ideal. But if I move the routes to routes/product.jsand load the Productsmodels:

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

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

I get an error saying that object has no method findAll.

我收到一条错误消息,说该对象没有方法findAll

What am I doing wrong? How can I remove the routes from app.js?

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

采纳答案by Aivaras

As of express 4.x Routeris added to support your case.

从 express 4.x 开始Router,添加了支持您的案例。

A router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.

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

Example from expressjs site:

来自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;

Then in app.js:

然后在 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

回答by Camilo Martin

Since I don't like repetition, here's what I do:

因为我不喜欢重复,所以我这样做:

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

And each file in routes is like:

路由中的每个文件都类似于:

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

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

module.exports = router;

This way you can avoid long repetitive lists like this one:

通过这种方式,您可以避免像这样的长重复列表:

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


Edit:these long examples assume each route file contains something like the following:

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

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

All of them could be mounted to "root", but what for them is "root", is actually a specific path given to app.use, because you can mount routes into specific paths (this also supports things like specifying the path with a regex, Express is quite neat in regards to what you can do with routing).

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

回答by Peter Gerasimenko

I can suggest you this file structure (according to Modular web applications with Node.js and Express from tjholowaychuk):

我可以建议你这个文件结构(根据来自 tjholowaychuk 的带有 Node.js 和 Express 的模块化 Web 应用程序):

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

user-apiand static-pagesexport expressjs applications, you can easily mount them in app.js. In usersmodule you can describe some Data Access operations and all methods about manipulating with the User entity (like create, update etc.). Our API module will use all these methods.

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

And here is sample code of app.js file (without common express stuff, only mounting routes from different modules):

下面是 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);

To use your modules this way you must start your app like this NODE_PATH=modules node app.js(i put this line to package.json file in scripts section).

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

Here is sample code of usersmodule:

这是users模块的示例代码:

index.js

索引.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(with Mongoose stuff for example of course!)

model.js(当然还有猫鼬的东西!)

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

And example of user-apimodule (here is the main part of the answer about separating routes and models).

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

And example of static-pages. If you are not going to build a kind of REST interface you may simply create several modules that will render pages only.

和的例子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});
});

Of course you can do whatever you want with modules. The main idea about expressjs is to use a lot of small apps instead of single one.

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

About nodejs modules you can read stackoverflowand docs.

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

Hope this helps.

希望这可以帮助。