搭建一个中级应用的 Express 项目框架

Node.js 对前端来讲无疑具备里程碑意义,在其愈来愈流行的今天,掌握 Node.js 已经再也不是加分项,而是前端攻城师们必需要掌握的技能。本文将完搭建 Express + MySQL的中级服务端应用,经过 express-generator 搭建 express 项目,以及 express 项目如何与数据库交互、 express项目如何记录日志、以及利用 domain 捕获 uncaughtException 异常,解决 Node 服务退出登问题;已经将项目框架完整的代码上传到 github,github地址为: github.com/fengshi123/…,欢迎 star....

1、Express-generator建立Express应用骨架

一、安装 express 生成器 express-generator

$ npm install -g express-generator复制代码
二、安装 express

$ npm install -g express复制代码
三、初始化项目,项目名称为 backend

$ express backend复制代码
四、安装依赖

$ cd backend
$ npm install复制代码
五、项目的骨架结构


  • /bin:用于应用启动
  • /public: 静态资源目录
  • /routes:能够认为是controller(控制器)目录
  • /views:jade模板目录,能够认为是view(视图)目录
  • app.js:程序main文件
六、启动项目

$ npm start复制代码
浏览器访问截图以下所示:


2、Express 结合 MySQL 数据库

一、首先安装配置好 MySQL 数据库,具体操做能够参照如下连接: supportopensource.iteye.com/blog/141552…
以及安装一个数据库管理工具 navicat for mysql

二、编写 mysql sql 脚本,咱们只要执行 setup.sh 脚本进行自动建立表等 sql 操做:
(1) setup.sh 的功能为链接 mysql 数据库,而且切换数据库,执行对应的 sql 脚本文件,脚本代码以下:

#!/bin/bash
mysql -uroot -p123456 --default-character-set=utf8 <<EOF
drop database if exists research;
create database research character set utf8;
use research;
source init.sql;
EOF
cmd /k复制代码
(2) init.sql 的功能为 添加要执行的 sql 脚本文件,脚本代码以下:

source t_user.sql;复制代码
(3) t_user.sql 功能为建立表 t_user,并插入对应数据:

create table if not exists t_user( 
  uid varchar(16) primary key, 
  name varchar(16),  
  sex varchar(16)
) default charset = utf8;
insert into t_user values('1','teacher','男');
insert into t_user values('2','teacher1','女');
commit;复制代码
三、结合 express mysql,建立如下目录文件:
conf/db.js 链接 mysql数据库
dao 与数据库交互
(1) conf/db.js,编写 mysql 数据库链接配置

// MySQL数据库联接配置
module.exports = { 
  mysql: {   
    host: '127.0.0.1',    
    user: 'root',   
    password: '123456',    
    database: 'research',   
    port: 3306  
  }
};复制代码
(2) dao/userSqlMapping.js,编写 CURD sql 语句:

// CRUD SQL语句
const user = {  
   insert: 'insert into t_user(uid, name, sex) VALUES(?,?,?)',  
   update: 'update t_user set name=?, sex=? where uid=?',  
   delete: 'delete from t_user where uid=?',  
   queryById: 'select * from t_user where uid=?',  
   queryAll: 'select * from t_user'};module.exports = user;
}复制代码

(3) dao/userDao.js,数据库 CURD 的具体实现,示例以下:

add: function (req, res, next) {    
pool.getConnection(function (err, connection) {     
 if (err) {        
     logger.error(err);        
     return;      
  }     
  // 获取前台页面传过来的参数      
  var param = req.body;     
  // 创建链接,向表中插入值      
  connection.query(sql.insert, [param.uid, param.name, param.age], function (err, result) {  
   if (err) {         
      logger.error(err);        
   } else {          
      result = {           
        code: 0,           
         msg: '增长成功'         
      };        
   }       
  // 以json形式,把操做结果返回给前台页面        
  jsonWrite(res, result);        
  // 释放链接        
  connection.release();     
  });    
});  
},复制代码

(4) routes/users.js 路由匹配对应的数据库操做:

// 增长用户
router.post('/addUser', function (req, res, next) {  
   userDao.add(req, res, next);
});复制代码

3、日志记录

一、 morgan:express 自带的 http 请求日志中间件
morganexpress默认的日志中间件,也能够脱离 express,做为 node.js的日志组件单独使用, morgan的具体 api 可参考 github: github.com/expressjs/m…
(1)项目中使用其来记录请求的日志,代码以下:

const logger = require('morgan');
// 输出日志到目录
var accessLogStream = fs.createWriteStream(path.join(__dirname, '/log/request.log'), 
{ flags: 'a', encoding: 'utf8' }); /
/ 记得要先把目录建好,否则会报错
app.use(logger('combined', { stream: accessLogStream }));复制代码
(2)日志记录截图以下:
二、winston
因为 morgan 只能记录 http请求的日志,因此咱们还须要 winston 来记录其它想记录的日志,例如:访问数据库出错等; WinstonNode.js 上最流行的日志库之一。它被设计为一个简单通用的日志库,支持多种传输(一种传输实际上就是一种存储设备,例如日志存储在哪里)。 winston中的每个 logger 实例在不一样的日志级别能够存在多个传输配置;固然 它也能够记录请求记录。 winston 的具体 api 可参考 github: github.com/winstonjs/w…
(1)项目中使用 winston 的代码以下:

/*  多container及多transport组合 */
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, printf } = format;
const path = require('path');
const myFormat = printf(({ level, message, label, timestamp }) => {  
    return `${timestamp} ${level}: ${message}`;
});
const logger = createLogger({  
     level: 'error',  
     format: combine(    timestamp(),    myFormat  ), 
     transports: [    
         new (transports.Console)(),   
         new (transports.File)({      
            filename: path.join(__dirname, '../log/error.log')   
            }) 
          ]
       });
module.exports = logger;


const logger = require('../common/logger'); 
logger.error(err);复制代码
(2)日志记录截图以下:


4、处理 uncaughtException 错误致使的node 服务退出

Node 0.8 以后的版本新增了 domain 模块,它能够用来捕获回调函数中抛出的异常。
domain 主要的 API domain.runerror 事件。简单的说,经过 domain.run 执行的函数中引起的异常均可以经过 domain error 事件捕获。咱们在 express 中项目中使用 domain 的代码以下:

// 处理没有捕获的异常,致使 node 退出
app.use(function (req, res, next) {  
  var reqDomain = domain.create();  
  reqDomain.on('error', function (err) {   
     res.status(err.status || 500);    
     res.render('error'); 
  }); 
  reqDomain.run(next);
});复制代码


5、express-jwt 实现 token 认证功能

express-jwt 是 nodejs 的一个中间件,他来验证指定 http 请求的 JsonWebTokens 的有效性,若是有效就将JsonWebTokens 的值设置到 req.user 里面,而后路由到相应的 router。 此模块容许您使用 Node.js 应用程序中的 JWT 令牌来验证HTTP请求。前端

(1)安装node

npm install express-jwt复制代码

(2)token 设置mysql

var expressJWT = require('express-jwt');
// token 设置
app.use(expressJWT({  secret: CONSTANT.SECRET_KEY}).unless({  
// 除了这个地址,其余的URL都须要验证 
 path: ['/getToken', /^\/public\/.*/, /^\/user_disk\/.*/]}));复制代码

(3)uid 注入 和 获取git

// uid 注入 token 中
ret = {  
 code: 0, 
 data: {    
   token: jsonWebToken.sign({      
    uid: obj.uid    
 },CONSTANT.SECRET_KEY, {  
    expiresIn: 60 * 60 * 1    
   }), 
  }
};
// 获取 token 中的 uid
var uid = req.body.uid;复制代码


6、添加 ESlint 检查代码规范

为了让项目的代码风格保持良好且一致,故在项目中添加 eslint 来检查 js 代码规范;
(1)安装 eslint

npm install -g eslint复制代码
(2) eslint 初始化

eslint --init复制代码

7、总结

本文咱们主要介绍经过 express-generator 搭建 express 项目,以及 express 项目如何与数据库交互、 express项目如何记录项目日志、以及利用 domain 捕获 uncaughtException 异常,解决 node 服务退出登问题;已经将项目完整的代码实例上传到 github,github地址为: github.com/fengshi123/…,欢迎 star....
相关文章
相关标签/搜索