Express4搭建框架
目录结构
文件夹 | 描述 |
---|---|
app | 应用开发目录,采用多模块,存放Controller与Model的位置。 |
config | 配置文件存放目录 |
middleware | 自定义中间件位置 |
public | 公共发布存放目录 |
route | 路由文件存放目录 |
util | 全局工具函数与类库保存目录 |
view | 视图模板存放目录 |
配置文件
$ vim config/server.json
{
"development": {
"web": {
"host": "127.0.0.1",
"port": 3001,
"frontendName": "index",
"backendName": "admin",
"static":{
"maxAge": 31557600000
}
},
"gate": {
"host": "127.0.0.1",
"port": 3014
}
},
"production": {
"web": {
"host": "127.0.0.1",
"port": 3001,
"frontendName": "index",
"backendName": "admin",
"static":{
"maxAge": 31557600000
}
},
"gate": {
"host": "127.0.0.1",
"port": 3014
}
}
}
$ vim config/session.json
{
"development": {
"name":"connect.sid",
"secret":"session_secret",
"resave":true,
"saveUninitialized":false,
"cookie": {
"secret": false,
"maxAge": 3600000
}
},
"production": {
"name":"connect.sid",
"secret":"session_secret",
"resave":true,
"saveUninitialized":false,
"cookie": {
"secret": false,
"maxAge": 3600000
}
}
}
$ vim config/mysql.json
{
"development": {
"host": "127.0.0.1",
"port": 3307,
"user": "root",
"password": "root",
"database": "pomelo",
"charset": "utf8mb4"
},
"production": {
"host": "127.0.0.1",
"port": 3307,
"user": "root",
"password": "root",
"database": "pomelo",
"charset": "utf8mb4"
}
}
$ vim config/redis.json
{
"development": {
"host": "127.0.0.1",
"port": 6379,
"db": 10,
"pass": ""
},
"production": {
"host": "127.0.0.1",
"port": 6379,
"db": 10,
"pass": ""
}
}
应用入口
$ vim app.js
//加载Web框架
const express = require('express');
//加载中间件
const path = require("path");
const methodOverride = require("method-override");
const bodyParser = require("body-parser");
const redis = require("redis");
const session = require("express-session");
const RedisStore = require("connect-redis")(session);
const cookieParser = require("cookie-parser");
const uuid = require("uuid");
//创建应用
const app = express();
//获取当前环境变量
//const env = process.env.NODE_ENV || "development";
const env = app.get("env") || "development";
//路径设置
app.set('rootPath', __dirname);
app.set('basePath', path.join(__dirname, 'public'));
app.set('configPath', path.join(__dirname,'config'));
app.set('viewPath', path.join(__dirname,'view'));
app.set('routePath', path.join(__dirname,'route'));
app.set('appPath', path.join(__dirname, 'app'));
app.set('middlewarePath', path.join(__dirname, 'middleware'));
app.set('utilPath', path.join(__dirname, 'util'));
//获取服务器配置
const serverConfig = require(path.join(app.get("configPath"), "server"))[env];
const sessionConfig = require(path.join(app.get("configPath"), "session"))[env];
//const redisConfig = require(path.join(app.get("configPath"), "redis"))[env];
//const mysqlConfig = require(path.join(app.get("configPath"), "mysql"))[env];
//设置模块名称
app.set("frontendName", serverConfig.web.frontendName);
app.set('frontendControllerPath', path.join(app.get("appPath"), app.get("frontendName"),'controller'));
//创建Redis客户端
//const redisClient = redis.createClient();
//使用中间件
//使用method-override中间件通过设置HTTP头信息的X-HTTP-Method-Override字段设置自定义的请求方法
app.use(methodOverride("X-HTTP-Method-Override"));
//使用body-parse中间件解析HTTP请求中的req.body
app.use(bodyParser.urlencoded({limit:"5000MB", extended:true}));
app.use(bodyParser.json({limit:"5000MB"}));
//使用express-session中间件设置会话
app.use(session({
genid:(res)=>uuid.v1(),
name:sessionConfig.name,
secret:sessionConfig.secret,
resave:sessionConfig.resave,
saveUninitialized:sessionConfig.saveUninitialized,
cookie:sessionConfig.cookie,
//store:new RedisStore({client:redisClient})
}));
//使用cookie-parser中间件解析cookie
app.use(cookieParser());
//使用静态资源中间件默认路径
app.use(express.static(app.get("basePath"), serverConfig.web.static));
//视图设置
app.set('view engine', 'ejs');
app.set('views', app.get("viewPath"));
app.set('view options', {layout: false});
//自定义错误处理中间件
const Error = require(path.join(app.get("middlewarePath"), "error"));
app.use(Error.logErrors);
app.use(Error.clientErrorHandler);
app.use(Error.errorHandler);
//使用路由中间件
app.use("/", require(path.join(app.get("routePath"), "index"))(express, app, path));
//监听端口
console.log(`Web server has stared ${serverConfig.web.host}:${serverConfig.web.port}`);
app.listen(serverConfig.web.port, serverConfig.web.host);
错误中间件
$ vim middleware/error.js
/**
* 将请求和错误信息写入标准错误输出、日志或类似服务
* */
exports.logErrors = function(err, req, res, next){
console.error(err.stack);
next(err);
};
/**
* 捕获客户端错误
* */
exports.clientErrorHandler = function(err, req, res, next){
if(req.xhr){
res.status(500).send({"error":"something blew up"});
}else{
next(err);
}
};
/**
* 捕获所有错误
* */
exports.errorHandler = function(err, req, res, next){
res.status(500);
res.render("error", {error:err});
};
自定义错误视图
$ vim view/error.ejs
<%=error%>>
默认路由
$ vim route/index.js
module.exports = function(express, app, path){
const router = express.Router({caseSensitive:true});
const IndexController = require(path.join(app.get("frontendControllerPath"), "index"));
router.get("/", IndexController.index);
return router;
};
默认控制器
$ vim app/index/controller/index.js
exports.index = function(req, res, next){
//获取参数
const title = "index default";
//渲染页面
res.render("index/index", {title});
};
默认视图
$ vim view/index/index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%=title%></title>
</head>
<body>
<%=title%>
</body>
</html>