學習 | egg.js 中間件和插件

小小又開始學習了,此次學習的是中間件和插件。
此次將會對這兩個點,進行學習。mysql

中間件

對於egg.js 來講,中間件和express的中間件性質類似,和洋蔥模型相似。
這裏首先講解的是egg.js的中間件sql

關於洋蔥模型

首先來兩張圖來展現洋蔥模型。express

再來一個簡單的demonpm

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的中間件,輸出的內容以下json

1
2
3
2
1

執行的整體順序爲執行第五行的內容,cookie

console.log(1)

這是第五行的內容,輸出1
遇到next,輸出接着執行第二個中間件,輸出內容爲2.
繼續遇到next,進入第三個中間件,輸出內容爲3.
此時沒有next了,接着返回。
輸出第二個中間件的內容,爲2.
接着最後輸出第一個中間件,中間件內容爲1.
因此,執行結果爲app

12321

編寫中間件

在目錄中新建文件框架

app/middleware/gzip.js

在該目錄下新建相關的中間件koa

// 引入相關的包
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');
}

此時項目目錄以下
async

手動掛載中間件

中間件編寫完成之後,這裏進行手動的掛載中間件。
在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',
};

這樣就完成了對插件的使用

本章學習結束。

相關文章
相關標籤/搜索