前端集散地|学习 | egg.js 中间件和插件

小小又开始学习了,这次学习的是中间件和插件。
这次将会对这两个点,进行学习。
中间件 对于egg.js 来说,中间件和express的中间件性质相似,和洋葱模型类似。
这里首先讲解的是egg.js的中间件
关于洋葱模型 首先来两张图来展示洋葱模型。
前端集散地|学习 | egg.js 中间件和插件
文章图片

前端集散地|学习 | 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'); }

此时项目目录如下
前端集散地|学习 | egg.js 中间件和插件
文章图片

手动挂载中间件 中间件编写完成以后,这里进行手动的挂载中间件。
在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
前端集散地|学习 | egg.js 中间件和插件
文章图片

这样就完成了全局中间件的配置。
单个路由使用中间件 之前使用的是全局的中间件,这里使用单个路由的中间件。
编写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如下
前端集散地|学习 | egg.js 中间件和插件
文章图片

这样就完成了对中间件的使用
插件 这里进行学习的是插件相关的内容。
什么是插件 插件是一个迷你的应用,包含了 Service、中间件、配置、框架扩展等等
没有独立的Router 和 Controller
没有 plugin.js,只能声明依赖,不能决定是否开启。
使用插件 安装egg-mysql 依赖
npm i egg-mysql --save

再 config/plugin.js 中,声明插件。
exports.mysql = { enable: true, package: 'egg-mysql', };

这样就完成了对插件的使用
【前端集散地|学习 | egg.js 中间件和插件】本章学习结束。

    推荐阅读