插件目的是将分离 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();// 如果是多级目录,也是通过文件名访问
}
}
看了下代码,一些优化建议:
- 不要在 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 不好意思,原来的回答错误了
- 在使用loadToContext的时候,类会自动实例化,这里的代码是(egg-core/…/context_loader.js/93行)
- 我这里使用的是FileLoader,他不会自动实例化,如果是要使用FileLoader的话,需要自己new Class()来调用