Node.js 如何模块化nodejs+;expressjs代码
我在nodejs expressjs应用程序中将server.js作为主文件。在客户端,我使用angular js作为模板(而不是在服务器端使用JADE/EJS)。我想在服务器上模块化这个server.js文件,因为如果我的应用程序增长,它可能不好Node.js 如何模块化nodejs+;expressjs代码,node.js,express,Node.js,Express,我在nodejs expressjs应用程序中将server.js作为主文件。在客户端,我使用angular js作为模板(而不是在服务器端使用JADE/EJS)。我想在服务器上模块化这个server.js文件,因为如果我的应用程序增长,它可能不好 var express = require('express'); var app = express(); var fs = require("fs"); /** * Session */ var session = require('ex
var express = require('express');
var app = express();
var fs = require("fs");
/**
* Session
*/
var session = require('express-session');
app.use(session({secret: '!23',resave: false,saveUninitialized:false}));
var bodyParser = require('body-parser');
var mysql = require('mysql');
var async = require('async');
/**
* Connect to MySQL
*/
var config = require("./config");
var db = config.database;
var connection = mysql.createPool(db);
app.use( bodyParser.json() );
// Create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false });
/**
* Provide web directory
*/
app.use(express.static('public'));
app.post('/abc', function (req, res) {
//code
});
app.post('/xyz', function (req, res) {
//code
});
app.post('/test', function (req, res) {
//code
});
var server = app.listen(config.port);
假设我想在单独的文件中添加以下方法,比如test.js。我该怎么做
app.post('/test', function (req, res) {
//code
});
在主模块server.js中: 删除: 换成
app.use(require("./router"));
在同一目录中创建文件router.js并添加:
var express = require('express');
var router = new express.Router();
router.post('/abc', function (req, res) {
//code
});
router.post('/xyz', function (req, res) {
//code
});
router.post('/test', function (req, res) {
//code
});
module.exports = router;
编辑1:
您可以将路由拆分为多个文件(在大型应用程序中可能有数百条路由)。如何做到这一点,我给出了几个策略:
创建新文件,在其中配置更多路由(例如routes/route1.js、routes/route2.js):
在router.js中添加:
router.use(require("./routes/route1"));
router.use(require("./routes/route2"));
在route1.js和route2.js中,创建与router.js类似的结构:
var express = require('express');
var router = new express.Router();
//place for routes
module.exports = router;
编辑2:OP在评论中提出了一个问题:
但是,如果我连接到sql并在每个模块中使用查询,那么我为什么要这样做呢
需要在每个模块中添加mysql连接代码吗
当我们把代码分成多个模块时,我们应该尽量减少依赖性。但是,在每个模块或其他需要大量资源的任务中多个连接可能是一个糟糕的选择
我们可以在多个模块中共享公共资源实例。如何完成这项任务有多种方法
我将向你们展示一些基本的(我将忽略全球污染):
假设我们有objectmyCommonObjectInstance
,我们需要将它传递给多个模块
1) 在主模块(server.js)中:
现在,在routes中,您可以执行以下操作:
router.post('/test', function (req, res) {
var myCommonObjectInstance = req.app.get('someName');
//other code
});
2) 在主模块(server.js)中,让我们创建中间件,为req或res添加新属性:
app.use(function(req,res,next){
req.myCommonObjectInstance = myCommonObjectInstance;
next();//very important!!!
});
现在在路线模块中:
router.post('/test', function (req, res) {
var myCommonObjectInstance = req.myCommonObjectInstance;
//other code
});
3) 第三种流行的方法是注入模块,请查看此帖子以了解更多详细信息:简而言之,您可以创建带有参数的模块和导出函数。在主模块中导入函数时,传递参数 你的一个模组
module.exports = function (myCommonObjectInstance) {
//your code and you have access to myCommonObjectInstance
};
在主模块中
require('./yourmodule')(myCommonObjectInstance);
我通常将所有路由放在routes文件夹中的单独文件(例如users.js、workplaces.js等)中,然后在我的主文件中使用fs包包含它们,然后
/**
* Register Routes Folder For Including New Routes
*/
fs.readdir('./routes', function(err, files){
files.forEach(function(fn) {
if(!/\.js$/.test(fn)) return;
require('routes/' + fn)(app, io);
});
});
使用此选项可用于脚手架:
app.js
将所有内容路由到一个路由定义文件
app.use('/api',require('./routes/api/allRoutes'));
allRoutes.js has all route definitions with controllers definitions
var roleCtrl=require('../master/role');
router.route('/role').post(roleCtrl.create);
router.route('/role/:roleId?').get(roleCtrl.retrieve);
我的role.js
如下所示:
const {ObjectId} = require('mongodb');
module.exports =roleObj=
{
collection: require(__basedir+'/config/config').clientName +'role',
create: function (req, res) {
var db = req.app.db;
var role =
{
roleName: req.body.roleName,
documentStatus:req.body.documentStatus||null,
auditTrail :[ {timeStamp:null , userID:null, userName:null , change:null } ]
};
db.collection(roleObj.collection).insertOne(role).then(function(result)
{
var response={_id:result.insertedId, message:"inserted", success:true};
res.send(response);
});
},
retrieve: function (req, res) {
var db = req.app.db;
var input = {};
if (req.params.roleId != undefined)
input['_id'] = ObjectId(req.params.roleId);
db.collection(roleObj.collection).find(input).toArray(function (err, result)
{
if (result.length != 0) res.send(result);
else res.send("empty");
});
}
}
当我在main server.js文件中使用app.use时,它抛出类型错误:app.use()需要中间件函数app.use必须将require('yourroutemodule')作为参数,并且yourroutemodule必须具有
var express=require('express')代码>var router=new express.router()
module.exports=路由器代码>您的错误意味着您没有将模块传递给应用程序。是的,这解决了问题,谢谢,但如果我连接到sql并在每个模块中使用查询,那么为什么我需要在每个模块中添加mysql连接代码?我不能在server.ja中使用通用代码吗?我会在Edit2
部分编辑答案并为您的评论问题添加答案
app.use('/api',require('./routes/api/allRoutes'));
allRoutes.js has all route definitions with controllers definitions
var roleCtrl=require('../master/role');
router.route('/role').post(roleCtrl.create);
router.route('/role/:roleId?').get(roleCtrl.retrieve);
const {ObjectId} = require('mongodb');
module.exports =roleObj=
{
collection: require(__basedir+'/config/config').clientName +'role',
create: function (req, res) {
var db = req.app.db;
var role =
{
roleName: req.body.roleName,
documentStatus:req.body.documentStatus||null,
auditTrail :[ {timeStamp:null , userID:null, userName:null , change:null } ]
};
db.collection(roleObj.collection).insertOne(role).then(function(result)
{
var response={_id:result.insertedId, message:"inserted", success:true};
res.send(response);
});
},
retrieve: function (req, res) {
var db = req.app.db;
var input = {};
if (req.params.roleId != undefined)
input['_id'] = ObjectId(req.params.roleId);
db.collection(roleObj.collection).find(input).toArray(function (err, result)
{
if (result.length != 0) res.send(result);
else res.send("empty");
});
}
}