小小又開始學習了,這次學習的是中間件和插件。
這次將會對這兩個點,進行學習。
中間件
對於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);
};
這樣就完成了對中間件的使用
插件
這裡進行學習的是插件相關的內容。
什麼是插件
插件是一個迷你的應用,包含了 Service、中間件、配置、框架擴展等等
沒有獨立的Router 和 Controller
沒有 plugin.js,只能聲明依賴,不能決定是否開啟。
使用插件
安裝egg-mysql 依賴
npm i egg-mysql --save
再 config/plugin.js 中,聲明插件。
exports.mysql = {
enable: true,
package: 'egg-mysql',
};
這樣就完成了對插件的使用
本章學習結束。