一、前言
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);
|