midwayjs / midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
https://www.midwayjs.org/
MIT License
7.4k stars 577 forks source link

引入egg插件出错, is not valid in current context #166

Closed xluos closed 5 years ago

xluos commented 5 years ago

在Midway中如何使用egg的插件呢?官网写的@plugin('pluginName')就可以注入进去,但我想使用egg-jwt这个插件。引入后默认是关闭的,在配置中打开后就全部路由走这个插件的中间件了。而且在Controller里面也拿不到这个插件的实例(可能是我的使用方法有问题),关于插件部分的使用官网能否给个更详细点儿的例子,而不是一笔带过,谢谢!

//HomeController中
@provide()
@controller('/')
export class HomeController {

  @plugin('jwt')
  jwt: any;

  @config('jwt')
  jwtconfig: any;

  @get('/login')
  async login(ctx) {
    const jwtt = this.jwt.sign({ foo: 'bar' }, this.jwtconfig.secret);
    console.log(jwtt);
    ctx.body = `login ok!`;
  }
}
// plugin.ts
// had enabled by midway
export = {
  // static: true,
  jwt: {
    package: 'egg-jwt',
  },
};
// config.default.ts
config.jwt = {
    secret: '123456123',
    enable: true,
    ignore: '/login',
  };

错误信息 ERROR 73516 [-/::1/-/12ms GET /login] nodejs.Error: jwt is not valid in current context

czy88840616 commented 5 years ago

稍等,我看一下。

czy88840616 commented 5 years ago

简单写了个 demo 测试了一下,@plugin() 是能正常工作的,demo在此

分析可能不成功的原因:

插件的开启和使用方法由于和 egg 相同,就没有再次描述这块。简单介绍一下,@plugin() 其实就是简单的从 app 对象上拿特定的属性,比如@plugin('jwt'),其实就是 app['jwt'],代码在此

还有其他问题,可以提交 demo 或者再描述给我。


ps: 发现 jwt 正好有特定特定路由开启的需求,我们的 @controller/@get 针对特定方法的中间件我要支持下直接传 koa middleware…… #167

xluos commented 5 years ago

感谢您的帮助

简单介绍一下,@plugin() 其实就是简单的从 app 对象上拿特定的属性,比如@plugin('jwt'),其实就是 app['jwt']

这句一下就明白了@plugin()在做什么之前不清楚这个装饰器内部做了那些操作,这么一说就很清楚了,类比其他的装饰器大概也明白为什么那么用了。这句话我觉得应该在文档里提一下。

config 中的 enable 其实就是我设置plugin.ts 里需要 enable: true发现没有效果,瞎试的发现这边设置上了能开启,当然这个用法也没有用对。 看来你的demo后发现自己之前plugin.ts 里的配置的写法也是错误的,这个可能就是导致我之前操作时plugin.ts 里设置 enable: true无效的原因。 最后,其实真正错误的原因还是没有找出来,因为我把你demo里面的用法copy到我那里一份还是同样的报错,但是我重新 init 一个项目后同样的用法就得到了预期的结果。可能是我之前误改了那些文件或配置导致的问题吧。还好项目刚开始没写几个文件我觉得重新 init 一个项目

非常感谢您的帮助

czy88840616 commented 5 years ago

可能你新建的脚手架比较早,而npm install 之后生成了 package-lock.josn 文件,导致版本被锁定,依赖出现问题。

可以删了 package-lock.json 再试、

iceshu commented 4 years ago

你好我升级到了 midwmidayjs2 然后根据文档 win10操作系统 https://www.yuque.com/midwayjs/midway_v2/v1_upgrade_v2 升级了下依赖版本 发现 egg-jwt 使用有问题 image image

我把带有验证jwt的中间件干掉还是报错,但是我把 egg-jwt 这个plugin 删除就ok了 仓库地址 https://github.com/iceshu/cmstest bff文件夹内 先依赖升级然后 跑就会报错,而且啊 midway2感觉很慢 编译的时候 我也是SSD 按照操作流程走了一遍还是很慢。

czy88840616 commented 4 years ago

@iceshu 可以单开一个 issue,在 close 的 issue 下面回复很难有提醒..

另外 我发现,我们漏了一个 Middleware 的定义,正好补上。

czy88840616 commented 4 years ago

@iceshu 已发2.3.12,删了依赖 ,package-lock.json,重新装下看看,应该好了,另外,慢的问题可以参考:https://www.yuque.com/midwayjs/midway_v2/wm13lg

ZQun commented 4 years ago

@iceshu 引入插件报错还可以通过配置文件解决,如:

// config.default.ts
config.jwt = {
  credentialsRequired: false
} as {}

@czy88840616 已升级到2.3.12,但是还有个问题,在middleware中间件下通过@Plugin装饰器不能调用插件方法,返回undefined,如:


import { Provide, Plugin } from '@midwayjs/decorator';
import { IWebMiddleware, IMidwayWebNext } from '@midwayjs/web';
import { Context } from 'egg';

@Provide()
export class authMiddleware implements IWebMiddleware {

    @Plugin()
    jwt: any

    resolve() {
        return async (ctx: Context, next: IMidwayWebNext) => {

            console.log('-->jwt', this.jwt) // undefined

            await next()
        }
    }
}
iceshu commented 4 years ago

@czy88840616 多谢我升级搞定了 @ZQun Z 我通过升级搞定了呢 其他没改 旧按照 https://www.yuque.com/midwayjs/midway_v2/v1_upgrade_v2 来的 今天用了mac 拉代码下来更新依赖。修改中间件代码 旧哦了呢 已经push到了github https://github.com/iceshu/cmstest

waitingsong commented 4 years ago

简单写了个 demo 测试了一下,@plugin() 是能正常工作的,demo在此

分析可能不成功的原因:

* plugin.ts 里需要 enable: true,而 config 中的 enable 我没看出来有啥用,可能是 jwt 的文档有误

* 配置中的 ignore 似乎我也没看到有对应的支持,[都是直接透传参数的](https://github.com/okoala/egg-jwt/blob/master/app/middleware/jwt.js#L6),看起来和直接使用 koa-jwt2 没有区别

插件的开启和使用方法由于和 egg 相同,就没有再次描述这块。简单介绍一下,@plugin() 其实就是简单的从 app 对象上拿特定的属性,比如@plugin('jwt'),其实就是 app['jwt'],代码在此

还有其他问题,可以提交 demo 或者再描述给我。

ps: 发现 jwt 正好有特定特定路由开启的需求,我们的 @controller/@get 针对特定方法的中间件我要支持下直接传 koa middleware…… #167

config 里面那个 enable 参数与 plugin.ts 文件中的 enable 参数是相同效果,都是用于开关插件。

// plugin.ts
export const jwt = {
  enable: true,  // <------------- 框架的开关
  package: '@waiting/egg-jwt',
}

差别在于 config 的开关是可以“动态”切换的,而后者貌似仅在框架启动时候一次性起效。

waitingsong commented 4 years ago

@xluos 你可以试试我这个轮子, @waiting/egg-jwt ,和 egg-jwt 差不多,不过对于ts支持更好(原生ts开发)。

czy88840616 commented 4 years ago

plugin 注入已修复。