Eggjs学习系列(九) 插件开发实践

本文档详细介绍了Egg.js框架的插件开发,包括如何搭建开发环境,插件的作用、写法及实践,以及遵循的开发规范。通过插件,可以扩展内置对象接口,插入自定义中间件,并进行应用初始化。示例展示了创建Websocket连接的插件开发过程,包括简单和进阶版本。遵循特定的命名和书写规范,以促进插件的复用和生态圈的建设。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插件机制是 Egg 框架的一大特色。它不但可以保证框架核心的足够精简、稳定、高效,还可以促进业务逻辑的复用,生态圈的形成。

插件也跟应用一样,包含了 Service、中间件、extend等等,没有独立的 Router 和 Controller,也没有 plugin.js 这份插件配置文件。

搭建开发环境

使用 Egg 提供的脚手架 egg-boilerplate-plugin 来开发插件

$ mkdir egg-hello && cd egg-hello
$ npm init egg --type=plugin
$ npm i
$ npm test

插件开发需要在 package.jsoneggPlugin 节点配置插件信息

{
   
   
  "name": "egg-rpc",
  "eggPlugin": {
   
     
    // 插件名(必须),生成插件名为 egg-{name}  
    "name": "rpc",
    // 插件依赖列表(可选),依赖插件没找到,应用启动失败  
    "dependencies": [ "registry" ],
    // 插件可选依赖列表(可选)  
    "optionalDependencies": [ "vip" ],
    // 指定环境开启插件(可选)
    "env": [ "local", "test", "unittest", "prod" ]
  }
}

插件是自己管理依赖的,应用在加载所有插件前会预先从它们的 package.json 中读取 eggPlugin > dependencieseggPlugin > optionalDependencies 节点,然后根据依赖关系计算出加载顺序

插件作用

插件主要有以下作用:

  • 支持扩展内置对象接口

    • app/extend/request.js - 扩展 Koa#Request 类
    • app/extend/response.js - 扩展 Koa#Response 类
    • app/extend/context.js - 扩展 Koa#Context 类
    • app/extend/helper.js - 扩展 Helper 类
    • app/extend/application.js - 扩展 Application 类
    • app/extend/agent.js - 扩展 Agent 类
  • 插入自定义中间件

    • app.js 中将中间件插入到合适位置

      // index 指插入位置, 插入中间件为 static
      app.config.coreMiddleware.splice(index, 0, 'static');
      
  • 应用启动时做一些初始化工作

    • 异步启动逻辑,可以使用 app.beforeStart API
    • 添加 agent 启动逻辑,使用 agent.beforeStart API
  • 设置定时任务

插件写法

对于使用同一服务可以产生多个实例的插件, Egg 提供了 app.addSingleton(name, creator) 方法来统一创建相应的服务。通过配置文件 config.js 里插件的 clientclients key来配置多个实例的属性。

下面是官方的 egg-mysql 案例

// egg-mysql/app.js
module.exports = app => {
   
   
  // 第一个参数 mysql 指定了挂载到 app 上的字段,我们可以通过 `app.mysql` 访问到 MySQL singleton 实例
  // 第二个参数 createMysql 接受两个参数(config, app),并返回一个 MySQL 的实例
  app.addSingleton('mysql', createMysql);
}

/**
 * @param  {Object} config   框架处理之后的配置项,如果应用配置了多个 MySQL 实例,会将每一个配置项分别传入并调用多次 createMysql
 * @param  {Application} app 当前的应用
 * @return {Object}          返回创建的 MySQL 实例
 */
function createMysql(config, app) {
   
   
  assert(config.host && config.port && config.user && config.database);
  // 创建实例
  const client = new Mysql(config);

  // 做启动应用前的检查
  app.beforeStart(async () => {
   
   
    const rows = await client.query('select now() as currentTime;');
    app.coreLogger.info(`[egg-mysql] init instance success, rds currentTime: ${
     
     rows[0].currentTime}`);
  });

  return client;
}

单实例的文件配置

// config/config.default.js
module.exports = {
   
   
  mysql: {
   
   
    client: {
   
   
      host: 'mysql.com',
      port: '3306',
      user: 'test_user',
      password: 'test_password',
      database: 'test',
    },
  },
};

多实例的文件配置

// config/config.default.js
exports.mysql = {
   
   
  clients: {
   
   
    // clientId, access the client instance by app.mysql.get('clientId')
    db1: {
   
   
      user: 'user1',
      password: 'upassword1',
      database: 'db1',
    },
    db2: {
   
   
      user: 'user2',
      password: 'upassword2',
      database: 'db2',
    },
  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值