一、前言
nodejs作为轻量级的web框架,在一些小项目上有着生态丰富, 开发快, 易运维的绝对优势。本篇博客是对阿里egg.js框架的学习记录, 最初写于2018年,更多特性请关注官网。
 二、初始化
我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目:
1 2 3 4
   | $ npm i egg-init -g $ egg-init egg-learn --type=simple $ cd egg-learn $ npm i
   | 
 
启动项目 npm run dev , 然后用webstorm导入项目
 三、项目搭建
框架提供了 egg-mysql 插件来访问 MySQL 数据库。这个插件既可以访问普通的 MySQL 数据库,也可以访问基于 MySQL 协议的在线数据库服务。
 安装与配置
安装对应的插件 egg-mysql :
开启插件:
1 2 3 4 5
   |  exports.mysql = {   enable: true,   package: 'egg-mysql', };
 
  | 
 
单数据源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   |  config.mysql = {          client: {                  host: 'localhost',                  port: '3306',                  user: 'root',                  password: 'root',                  database: 'test',     },          app: true,          agent: false, };
 
  | 
 
 创建数据库文件
初始化表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | /*  Navicat Premium Data Transfer
   Source Server         : localhost  Source Server Type    : MySQL  Source Server Version : 50717  Source Host           : localhost  Source Database       : test
   Target Server Type    : MySQL  Target Server Version : 50717  File Encoding         : utf-8
   Date: 01/19/2018 10:44:32 AM */ DROP TABLE IF EXISTS `egg_user`; CREATE TABLE `egg_user` (     `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',     `name` varchar(32) DEFAULT NULL COMMENT '用户名',     PRIMARY KEY (`id`) )  ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
   | 
 
 Service层
由于对 MySQL 数据库的访问操作属于 Web 层中的数据处理层,因此我们强烈建议将这部分代码放在 Service 层中维护。
下面是一个 Service 中访问 MySQL 数据库的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   |  const Service = require("egg").Service;
  class IndexService extends Service{
           async insert(){         const result = await this.app.mysql.insert("egg_user",{name:"admin"});         return {result};     }
           async find(){         const result = await this.app.mysql.get("egg_user",{id:1});         return {result};     } }
  module.exports = IndexService;
 
  | 
 
 Controller层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   |  const Controller = require("egg").Controller;
  class IndexController extends Controller{
      async insert(){         console.log("插入数据");         const ctx = this.ctx;         const result = await ctx.service.index.insert();         ctx.body = result;     }
      async find(){         console.log("查询数据");         const ctx = this.ctx;         const result = await ctx.service.index.find();         ctx.body = result;     } }
  module.exports = IndexController;
 
  | 
 
 路由配置
1 2 3 4 5 6 7
   |  module.exports = app => {   const { router, controller } = app;   router.get('/', controller.home.index);   router.get('/insert', controller.index.insert);   router.get('/find', controller.index.find); };
 
  | 
 
启动项目即可测试
 四、中间件
中间件支持以下几种方式:
在应用中使用中间件、
在框架和插件中使用中间件、
在路由中使用中间件
我们只介绍在路由中使用中间件,只需对路由文件改造即可:
1 2 3 4 5 6 7 8 9
   | module.exports = app => {   const { router, controller } = app;      const logger = app.middleware.logger();      router.get('/', logger, controller.home.index);   router.get('/insert', logger,  controller.index.insert);   router.get('/find', logger,  controller.index.find); };
  | 
 
中间件文件如下:
1 2 3 4 5 6 7 8
   |  module.exports = options => {     return async function logger(ctx,next) {         console.log("中间件in");         await next();         console.log("中间件out");     }; };
 
  | 
 
 五、模板
框架内置 egg-view 作为模板解决方案,并支持多模板渲染,每个模板引擎都以插件的方式引入,但保持渲染的 API 一致。
以下以官方支持的 View 插件 egg-view-nunjucks 为例
 引入view插件
1
   | npm i egg-view-nunjucks --save
   | 
 
 启用插件
1 2 3 4 5
   |  exports.nunjucks = {   enable: true,   package: 'egg-view-nunjucks', };
 
  | 
 
 配置插件
1 2 3 4 5 6
   | config.view = {     defaultViewEngine: 'nunjucks',     mapping: {         '.html': 'nunjucks',     }, };
  | 
 
 创建模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | //app/view/index.html
  <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Title</title> </head> <body>     <div>         <h2>欢迎您 {{result.name}}</h2>a     </div>
  </body> </html>
   | 
 
 Controller
1 2 3 4 5 6
   | async indexView(){     console.log("渲染模板");     const ctx = this.ctx;     const result = await ctx.service.index.find();     await ctx.render("index.html",result); }
  | 
 
 路由
1
   | router.get('/view', logger,  controller.index.indexView);
  |