小小又开始学习了,这次学习的是中间件和插件。
这次将会对这两个点,进行学习。
中间件
对于 egg.js 来说,中间件和 express 的中间件性质类似,和洋葱模型相似。
这里首先解说的是 egg.js 的中间件
对于洋葱模型
首先来两张图来展现洋葱模型。
再来一个简略的 demo
const Koa = require('koa');
const app = new Koa();
const PORT = 3000;
// #1
app.use(async (ctx, next)=>{console.log(1)
await next();
console.log(1)
});
// #2
app.use(async (ctx, next) => {console.log(2)
await next();
console.log(2)
})
app.use(async (ctx, next) => {console.log(3)
})
app.listen(PORT);
console.log(`http://localhost:${PORT}`);
执行该 koa 的中间件,输入的内容如下
1
2
3
2
1
执行的总体程序为执行第五行的内容,
console.log(1)
这是第五行的内容,输入 1
遇到 next,输入接着执行第二个中间件,输入内容为 2.
持续遇到 next,进入第三个中间件,输入内容为 3.
此时没有 next 了,接着返回。
输入第二个中间件的内容,为 2.
接着最初输入第一个中间件,中间件内容为 1.
所以,执行后果为
12321
编写中间件
在目录中新建文件
app/middleware/gzip.js
在该目录下新建相干的中间件
// 引入相干的包
const isJSON = require('koa-is-json');
const zlib = require('zlib');
async function gzip(ctx, next) {await next();
// 后续中间件执行实现后将响应体转换成 gzip
let body = ctx.body;
if (!body) return;
if (isJSON(body)) body = JSON.stringify(body);
// 设置 gzip body,修改响应头
const stream = zlib.createGzip();
stream.end(body);
ctx.body = stream;
ctx.set('Content-Encoding', 'gzip');
}
此时我的项目目录如下
手动挂载中间件
中间件编写实现当前,这里进行手动的挂载中间件。
在 config.default.js 目录中,配置相干的中间件。
/* eslint valid-jsdoc: "off" */
'use strict';
/**
* @param {Egg.EggAppInfo} appInfo app info
*/
module.exports = appInfo => {
/**
* built-in config
* @type {Egg.EggAppConfig}
**/
const config = exports = {};
// use for cookie sign key, should change to your own and keep security
config.keys = appInfo.name + '_1595046215730_9281';
// add your middleware config here
// 增加中间件
config.middleware = [];
// add your user config here
const userConfig = {// myAppName: 'egg',};
return {
...config,
...userConfig,
};
};
编写配置相干的中间件。
配置实现当前文件如下
/* eslint valid-jsdoc: "off" */
'use strict';
/**
* @param {Egg.EggAppInfo} appInfo app info
*/
module.exports = appInfo => {
/**
* built-in config
* @type {Egg.EggAppConfig}
**/
const config = exports = {};
// use for cookie sign key, should change to your own and keep security
config.keys = appInfo.name + '_1595046215730_9281';
// add your middleware config here
// 增加中间件
config.middleware = ['gzip'];
// add your user config here
const userConfig = {// myAppName: 'egg',};
return {
...config,
...userConfig,
};
};
这就实现了中间件的配置。
因为我的项目会进行主动重启,所以关上 devtool,这里能够看到曾经配置好的 gzip
这样就实现了全局中间件的配置。
单个路由应用中间件
之前应用的是全局的中间件,这里应用单个路由的中间件。
编写 app/router.js 配置文件
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {const { router, controller} = app;
router.get('/', controller.home.index);
};
这里为了更加不便的展现,对中间件函数进行了批改
const isJSON = require('koa-is-json');
const zlib = require('zlib');
module.exports = options => {return async function gzip(ctx, next) {console.log(333);
await next();
// 后续中间件执行实现后将响应体转换成 gzip
let body = ctx.body;
if (!body) return;
// 反对 options.threshold
if (options.threshold && ctx.length < options.threshold) return;
if (isJSON(body)) body = JSON.stringify(body);
// 设置 gzip body,修改响应头
const stream = zlib.createGzip();
stream.end(body);
ctx.body = stream;
ctx.set('Content-Encoding', 'gzip');
};
};
再次批改 router.js 配置文件
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {const { router, controller} = app;
const gzip = app.middleware.gzip({threshold: 1024});
router.get('/', gzip ,controller.home.index);
};
拜访链接,http://127.0.0.1:7002/
查看 log 如下
这样就实现了对中间件的应用
插件
这里进行学习的是插件相干的内容。
什么是插件
插件是一个迷你的利用,蕴含了 Service、中间件、配置、框架扩大等等
没有独立的 Router 和 Controller
没有 plugin.js,只能申明依赖,不能决定是否开启。
应用插件
装置 egg-mysql 依赖
npm i egg-mysql --save
再 config/plugin.js 中,申明插件。
exports.mysql = {
enable: true,
package: 'egg-mysql',
};
这样就实现了对插件的应用
本章学习完结。