资讯专栏INFORMATION COLUMN

egg.js插件分析

Kahn / 962人阅读

摘要:前言之前对的整体设计有过自己的理解,在中方便的插件机制也是这个框架的一大亮点,本文主要就是从的插件开始,对后台中的插件机制做一些分析和总结。插件的特点它包含了中间件配置框架扩展等等。插件其余部分的运行原理也是类似的。

前言

之前对egg.js的整体设计有过自己的理解,在egg.js中方便的插件机制也是这个框架的一大亮点,本文主要就是从egg.js的插件开始,对node后台中的插件机制做一些分析和总结。

插件

在koa的项目中可以发现有大量的中间件的使用,常见的中间件可以用来做,鉴权,请求的参数合并,错误的统一处理等等。
中间件的特点大概总结一下就是:

会对请求进行处理,并且影响在请求上

中间件有自己的加载顺序,不同的顺序可能会带来不同的结果,整个koa形成了一个类似洋葱圈的模型

这样就会发现整个项目中确实有一些部分的功能不适合放到中间件中,比如与请求无关的功能,需要在初始化中就执行的功能,需要管理中间件功能的功能,这个时候就需要用到插件的功能了。
egg插件的特点:

它包含了 Service、中间件、配置、框架扩展等等。

它没有独立的 Router 和 Controller。

基本上插件和一个独立的应用没有多大的区别。

插件的加载

前面说到了egg的插件其实可以直接看作是一个小的应用,从目的上可以当作是一些公共功能的egg应用的抽象,那么这些插件究竟是如何被使用的呢?
首先是整个egg的应用的加载,可以从源码中看到分为了三个部分

/**
   * loadUnit is a directory that can be loaded by EggLoader, it has the same structure.
   *
   * The order of the loadUnits:
   *
   * 1. plugin
   * 2. framework
   * 3. app
   */
  getLoadUnits() {
    const dirs = this.dirs = [];

    if (this.orderPlugins) {
      for (const plugin of this.orderPlugins) {
        dirs.push({
          path: plugin.path,
          type: "plugin",
        });
      }
    }

    // framework or egg path
    for (const eggPath of this.eggPaths) {
      dirs.push({
        path: eggPath,
        type: "framework",
      });
    }

    // application
    dirs.push({
      path: this.options.baseDir,
      type: "app",
    });
    
    return dirs;
  }

运行的结果

[ { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-session",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-security",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-jsonp",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-onerror",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-i18n",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-watcher",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-multipart",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-development",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-schedule",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-logrotator",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-static",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-view",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-sequelize",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-view-art",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg-validate",
    type: "plugin" },
  { path: "/Users/qitmac000458/Workspace/developer/node_modules/egg",
    type: "framework" },
  { path: "/Users/qitmac000458/Workspace/developer", type: "app" } ]

可以认为这每一个都是一个独立的app,之后就是如何把这些应用整合成一个app。那么简单的来看,只看app.js的整合吧

loadFile(filepath, ...inject) {
    if (!fs.existsSync(filepath)) {
      return null;
    }

    const ret = utils.loadFile(filepath);
    // function(arg1, args, ...) {}
    if (inject.length === 0) inject = [ this.app ];
    return isFunction(ret) ? ret(...inject) : ret;
 }
 loadCustomApp() {
    this.getLoadUnits()
      .forEach(unit => this.loadFile(path.join(unit.path, "app.js")));
  },

再回忆一下app.js的一般写法,也就是

module.exports = app => {
  do something
};

这样插件中的每个app.js就都得已运行,并且运行顺序也就很容易知道,是和getLoadUnits的运行结果是一致的。插件其余部分的运行原理也是类似的。

总结

在了解了整个egg插件机制后,编写一个插件其实就变得很容易了,或者说后面可以从业务代码中直接沉淀出一整个功能作为一个插件。
egg的插件的加载几乎是复用了整个loader,将插件的功能于原本app的业务功能实现了解耦,而又保持了一个egg微应用的整体结构,这块的设计也是很值得学习的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93341.html

相关文章

  • 基于Egg框架的日志链路追踪实践分享

    摘要:项目扩展自定义日志中间件封装好之后,在实际项目应用中我们还需要一步操作,提供了框架扩展功能,包含五项,可以对这几项进行自定义扩展,对于日志因为每次日志记录我们需要记录当前请求携带的做一个链路追踪,需要用到是的请求上下文扩展项。 快速导航 [Logger-Custom] 需求背景 [Logger-Custom] 自定义日志插件开发 [Logger-Custom] 项目扩展 ...

    EscapedDog 评论0 收藏0
  • 阿里egg.js初体验(一)

    摘要:是阿里推出的基于的开发框架,今天抽空体验了下,按官方教程做一个。用于解析用户的输入,处理后返回相应的结果,具体参见。用于编写业务逻辑层,可选,建议使用,具体参见。和用于自定义启动时的初始化工作,可选,具体参见启动自定义。 egg.js是阿里推出的基于koa的node开发框架,今天抽空体验了下,按官方教程做一个Hacker News。其实官方有脚手架提供,但是这次我们不用。 开始之前,我...

    Dr_Noooo 评论0 收藏0
  • Eggjs小试

    摘要:项目都很小,但为了进一步了解,特意选择了作为框架基础开发后端服务。能将请求限制在同源网站,即只有拥有专有令牌的网站发送请求才会正确响应。项目生产静默部署,启动使用,停止使用。不足工具函数的访问需要自己手动添加扩展另没有写测试,希望下次补上。 前言 这段时间,用Eggjs作为后端服务框架开发了几个项目。项目都很小,但为了进一步了解Eggjs,特意选择了Eggjs作为框架基础开发后端服务。...

    waltr 评论0 收藏0
  • Egg.js学习

    摘要:如果需要在构造函数做一些处理,一定要有这句话,才能保证后面的使用。文件夹里面存放工具类引用拿到内置对象也就是进入这个文件页面渲染使用的是页面模板在里面添加添加渲染 egg.js是什么 是一个node.js的后台web框架,类似的还有express,koa 优势:规范、插件机制Egg.js约定了一套代码目录结构(配置config、路由router、扩展extend、中间件middlewa...

    xiangchaobin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<