发布了一个egg的插件 egg-helper
发布于 6 年前 作者 yuezm 5878 次浏览 来自 分享

插件目的是将分离 app/extend/helper.js ,分成app/helper/*.js 的单个文件 egg-helper 自动读取 app/helper目录下的所有文件,并按照文件名为key的方式,挂在ctx.helper上,你可以直接使用 ctx.helper[filename][function]来使用,无需在文件中再次引入 优点:

  • 不会覆盖egg原有的helper.js
  • 自动读取helper目录下的所有文件,无需手动引入,并挂载在ctx.helper上
  • 可以使用多级目录

链接:egg-helper

使用 // {app_root}/config/plugin.js exports.helper = { enable: true, package: ‘egg-helper’, };

示例 Add the util.js file to the app/helper folder

// app/helper/util.js
module.exports = app => {
    return {
        foo() {
            // app is Application Object
            console.log(app);
            return 'hello helper';
        },
    };
};

如果想使用多级目录,例如:

// app/helper/util/util1.js
module.exports = app => {
    return {
        foo1() {
            // app is Application Object
            console.log(app);
            return 'hello helper';
        },
    };
};

in Controller

DemoController extends Controller{
	async index(){
		this.ctx.helper.util.foo(); // 通过如下路径可以访问到方法
		this.ctx.helper.util.util1.foo();// 如果是多级目录,也是通过文件名访问
	}
}
18 回复

看了下代码,一些优化建议:

  • 不要在 helper 里面再去做加载,直接在 app.js 里面调用 app.loader.loadToContext 的方式去扩展,或者通过 loadToApp 去覆盖掉 app.Helper ,可以参考下 loadService 等的源码
  • ${process.cwd()}/app/helper 这样只能拿到当前应用的,看下 loader 的 loadUnits 的概念
  • fs.readdirSync 可不好啊
  • app/helper/util.js 应该是放到 test 那边的

可以参考下这个源码:https://github.com/eggjs/egg-view-nunjucks/blob/master/lib/environment.js

@atian25 谢谢指导

@atian25 再次感谢,按照建议,改完科学多了

  • 加载那里,要用 loadUnits 这样所有框架和插件里面的都能被加载。
  • lower 等参数可以不加,加了似乎就全小写了
  • 现在的方式会覆盖掉原来的 helper.js 的规范,可能会影响到其他插件。其实可以挂为 ctx.utils

@atian25 谢谢指导,我再去看一下loadUnits,我们这边目前打算就是覆盖掉helper,以前工具函数是放在util目录下的,现在想按照egg取名,放在helper下面

@yuezm 需要考虑几个问题:

  • app/extend/helper/abc/xx.js 这种子目录要不要加载?加载后是 ctx.helper/abc.xx 还是?
  • egg-security 默认会挂一些 helper 的,你们覆盖的话就会影响到其他插件的,最好是 loadUnit 的时候,加上原来的 helper.js 的支持

@atian25 出现多级目录的话,会采用ctx.helper.abc.xx,那我这边添加原来的helper.js的支持

单文件不一定好加,可以看下源码 https://github.com/eggjs/egg-core/blob/master/lib/loader/file_loader.js#L148 要处理好几个点,包括 files,还有挂载的路径

@atian25 非常感谢!我下班去研究下

@atian25 感谢您的指导,我用FileLoader完成了初步版本

@yuezm cool~

  • 单元测试其实可以直接用 mockContext 来测试
  • lock 文件要删除
  • config 那个文件似乎没啥用,可以删除
  • REAMD 里面的示例,可以改为 2 space 缩进

@atian25 感谢您的指导,完成了helper插件

@caililin 主要是有大神指导

@atian25 请问如果要扩展一个model怎么操作呢? 就是把app/model文件夹下的文件自动加载。像Service那样 是一个类。会自动实例化。 试了下楼主的方法,是一个类的话直接就是返回类。不会自动实例化

@cjy520 你试试在调用 loadToContext 的时候,option参数加一个 call: true,应该就可以了

@cjy520 参考 egg-mongoose 和 egg-sequence 插件

@cjy520 不好意思,原来的回答错误了

  1. 在使用loadToContext的时候,类会自动实例化,这里的代码是(egg-core/…/context_loader.js/93行)
  2. 我这里使用的是FileLoader,他不会自动实例化,如果是要使用FileLoader的话,需要自己new Class()来调用
回到顶部