搭建一箇中級應用的 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....
相關文章
相關標籤/搜索