[eggjs/egg]egg 如何继承 framework 的 model、controller、router

2025-11-14 376 views
8

代码已经提交:https://github.com/ddzyan/gateway 我现在的目的是框架实现 router . model , controller 等一些重复部分内容,使 egg 继承使用,请问要怎么处理呢,或者说 framework 可以实现这方面的功能吗

回答

2

这个文档有说,egg 并未加载框架的上述目录,看下 Loader 代码。

5

即使我采用在 framework 配置文件中,额外在挂上目录。然后在 egg 中的路由中调用 app.baseController.home.index 也无法实现对 controller 的继承是吗, 现在的代码报错无法找到config,是因为我在写 baseController 里面的类的时候没有继承 Controller 吧

customLoader: {
      baseController: {
        directory: 'app/baseController',
        inject: 'app', // or app
        loadunit: true, // 是否加载框架和插件目录
        // other loads options
      },
    },
6

可以采用Loader挂在额外的目录方式,来实现 继承 framework controller 的方法吗? 现在我用的是额外挂个目录,在egg里面还是要写 controller ,只是在 controller 里面调用我额外挂载的目录

3

有一个方法算是黑魔法吧,可以这样:

  • 自定义一个 framework 就叫 myFramework 好了
  • 在 myFramework 里面 src/core 下面写自己的 baseController baseService 之类的
    
    const egg = require('egg')

class BaseController extends egg.Controller { getUserInfo() { ..... } }

module.exports = BaseController

* 然后在 myFramework 的根目录创建 `app.js`
```javascript
const BaseController = require('./app/core/controller')
const BaseService = require('./app/core/service')

class AppBootHook {
  constructor (app) {
    this.app = app
  }

  configWillLoad () {
    this.app.coreLogger.info('config will load')
  }

  configDidLoad () {
    this.app.coreLogger.info('config did load')
    const app = this.app
    // 替换 controller 为你写的 controller
    app.coreLogger.info('load base controller')
    app.Controller = BaseController
    require('egg').Controller = BaseController
    app.BaseController = BaseController
    require('egg').BaseController = BaseController

    // 替换 service 为你写的 service
    app.coreLogger.info('load base service')
    app.Service = BaseService
    require('egg').Service = BaseService
    app.BaseService = BaseService
    require('egg').BaseService = BaseService
 }
}

module.exports = AppBootHook
  • 然后你就可以在你的 egg 项目中使用 myFramework,定义 controller 或者 service 的时候直接继承并调用你自定义的方法了:

const { Controller } = require('egg');

class HomeController extends Controller { index() { const userInfo = this.getUserInfo(); .... } }


* 如果要 ts 的话,你还得自己写 d.ts 覆盖
6

当然,也有麻烦一点的,那就是在 framework 里面覆写 AppWorkerLoader 和 AgentWorkerLoader,然后将 loadController loadService loadRouter 给重新写了,具体可以参考 egg-core/ib/loader/mixin。 不过,我没试过。。。。

5

baseController baseService 本身就支持在应用级别覆盖的,在文档里面有提到

5

baseController baseService 本身就支持在应用级别覆盖的,在文档里面有提到

支持重写实例化controller的地方么?我想用proxy对controller进行一些扩展,但是没有找到相应的API

2

    loadController(opt) {
        const { app } = this
        super.loadController({
            directory: [
                path.join(__dirname, '../app/controller'),
                path.join(app.config.baseDir, 'app/controller')
            ],
            ignore: 'base*.js',
        })
        // super.loadController(opt)
    }
2

baseController baseService 本身就支持在应用级别覆盖的,在文档里面有提到

支持重写实例化controller的地方么?我想用proxy对controller进行一些扩展,但是没有找到相应的API

在 app.js 里面,把 app.BaseController 替换掉即可。

9

'use strict';

const path = require('path'); const egg = require('egg'); const Controller = require('./core/base_controller'); const Service = require('./core/base_service');

const EGG_PATH = Symbol.for('egg#eggPath');

class Application extends egg.Application { get [EGG_PATH]() { return path.dirname(__dirname); } }

class Agent extends egg.Agent { get [EGG_PATH]() { return path.dirname(__dirname); } }

module.exports = Object.assign(egg, { Application, Agent, Controller, Service });

@atian25 天猪大佬 如果使用framework的方式替换controller基类 可以吗,我再上层业务里requrie('egg').Controller的时候发现还是BaseContextClass