Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

egg-core #19

Closed
30 tasks done
atian25 opened this issue Jul 17, 2016 · 52 comments
Closed
30 tasks done

egg-core #19

atian25 opened this issue Jul 17, 2016 · 52 comments

Comments

@atian25
Copy link
Member

atian25 commented Jul 17, 2016

Loader

做到灵活性,扩展性强。

API

loader 只提供原子粒度的 API,由框架来自行组织

Env

  • getServerEnv
  • getEggPaths
  • getLoadUnits
  • getAppname

Low Level API

  • loadFile
  • loadToApp
  • loadToContext
  • loadExtend

High Level API

  • loadPlugin
  • loadConfig
  • loadController
  • loadMiddleware
  • loadApplicationExtend
  • loadContextExtend
  • loadRequestExtend
  • loadResponseExtend
  • loadHelperExtend
  • loadCustomApp
  • loadCustomAgent
  • loadService

和插件的关系

插件需要用到 loader 功能需要增加一个 loader 插件,比如 db 的功能

|- app
  `- db
    `- a.js

新增 egg-loader-db 插件

// app.js
module.exports = function(loader) {
  app.loader.loadToApp('app/db', 'db');
};

db 插件直接依赖 egg-loader-db 插件

load unit

每个加载单元的目录结构都是类似的,框架、插件、应用的路径都是称为 loadDir。

|- app
  |- extend
  |- service
  |- controller
  |- middleware
  `- router.js
|- config
  |- config.js
  `- plugin.js
|- agent.js
`- app.js

LoaderOptions

  • directory: null,
  • target: null,
  • ignore: undefined,
  • lowercaseFirst: false,
  • initializer: null,
  • call: true,
  • override: false,
  • inject: undefined,

Action

Core

egg-core 是包含了 loader 和应用初始化的功能,简单理解就是一个有目录约定的 koa,初始化包括了 loader。

  • loader
  • ready
  • logger
  • router

egg 就像其他框架一样只需要继承 egg-core 就可以直接使用


@atian25

嗯, 只需提供一个机制给框架开发者扩展, 如集团那边是有 proxy, 其他开发者可以定义:

this.db.xxx -> app/db/xxx.js
this.filters.xxx -> app/filters/xxx.js
@atian25 atian25 mentioned this issue Jul 17, 2016
3 tasks
@popomore popomore changed the title 增加一个 ctx 级别的通用 loader loader 重构 Jul 28, 2016
@popomore
Copy link
Member

popomore commented Jul 28, 2016

  • app.js/agent.js 支持返回一个 promise

@dead-horse
Copy link
Member

+1 直接支持 app.js 是一个 generator 或者 async function 吧

@dead-horse
Copy link
Member

需求很强烈,app.js 里面可能要做挺多逻辑的

@popomore
Copy link
Member

增加 strict 参数,有些 warn 的直接抛错

@jtyjty99999
Copy link
Member

jtyjty99999 commented Jul 29, 2016

load filter能支持就好了,感觉可以单独抽象

@popomore
Copy link
Member

filter 原来就有吧

@atian25
Copy link
Member Author

atian25 commented Jul 29, 2016

之前是在 view 里面单独做的

@popomore
Copy link
Member

popomore commented Jul 29, 2016

哦,懂了,我以为是 loader 参数。

helper 都应该放 view 里,先算了吧,view 有自己的 helper

@popomore
Copy link
Member

popomore commented Aug 2, 2016

原来的加载顺序是 app > framework > plugin > egg,所以 loader 需要提供一个 eggPath 来指定 egg 的目录。

https://github.com/eggjs/egg-loader/blob/master/lib/base_loader.js#L187

@popomore
Copy link
Member

popomore commented Aug 2, 2016

去除 eggPath 和 customEgg 参数,

  1. 顺序改为 app > framework > plugin,egg 作为 framework 的最底层,plugin 完全独立,无法覆盖 framework 和 app
  2. 继承 framework 必须指定 eggPath,所以不需要 customEgg 参数了。

@popomore popomore mentioned this issue Aug 2, 2016
25 tasks
@atian25
Copy link
Member Author

atian25 commented Aug 2, 2016

这个变更的出发点是?

@popomore
Copy link
Member

popomore commented Aug 2, 2016

去除复杂性

@popomore
Copy link
Member

popomore commented Aug 2, 2016

找 eggPaths 的时候是否需要强制指定当前框架的 eggPath

  1. 如果不强制指定,很容易忽略错误,某个框架未配置则忽略所有的文件。
  2. 如果强制指定,那会一直找到 koa,但是 koa 肯定不会配置的。

之前会指定 eggPath 参数为最底层的框架,但是这个变量容易被误解。

@fengmk2
Copy link
Member

fengmk2 commented Aug 2, 2016

找到 eggPath 就算到最底层了吧?egg 本身会依赖 koa,为何要 loader 去关注 koa 呢?

@popomore
Copy link
Member

popomore commented Aug 2, 2016

看上面,去除 eggPath 了

@fengmk2
Copy link
Member

fengmk2 commented Aug 2, 2016

没搞明白如何能做到去掉 eggPath 的,去掉了多层继承是怎么做到的?

@popomore
Copy link
Member

popomore commented Aug 2, 2016

这里说的 eggPath 是指 loader 的参数,指定最底层 egg 的路径。你说的 eggPath 是每层框架通过 symbol 来指定自己框架的路径。所以总是会存在理解差异,要去掉。一旦没有了最底层的 egg 路径,那么就不知道循环到哪里停止了,只能到 koa 了。

@popomore
Copy link
Member

popomore commented Aug 2, 2016

这里 egg-loader 是不感知 egg 存在的,如果感知可以在 egg 加个 isEgg 的参数。

@fengmk2
Copy link
Member

fengmk2 commented Aug 2, 2016

一直找到 package.name === egg 的那个模块不就行了?

@fengmk2
Copy link
Member

fengmk2 commented Aug 2, 2016

而且对于 npm3,根本无法递归找下去。。。

@popomore
Copy link
Member

popomore commented Aug 2, 2016

不是目录递归啊,是原型链

@fengmk2
Copy link
Member

fengmk2 commented Aug 2, 2016

egg 的 Application 设置一个 Application.isEgg = true 来判断是 egg 还是 koa?无法通过特殊值判断是否 koa Application 的。

@popomore
Copy link
Member

popomore commented Aug 3, 2016

eggPath 就是框架 path 吧,我把所有都改下好了
GaoXiaochen notifications@github.com于2016年8月3日 周三上午9:37写道:

Symbol.for('egg#eggPath') 建议改个名字,frameworkPath ? 不然老搞混


You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
#19 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAWA1TYYpv_pdRtnSWsBGdQZZiH2xnyrks5qb_DfgaJpZM4JOMI-
.

@gxcsoccer
Copy link
Contributor

gxcsoccer commented Aug 3, 2016

eggPath 我觉得就是 egg 的路径,上层的框架改成 egg#frameworkPath 这样没有歧义。

@popomore
Copy link
Member

popomore commented Aug 3, 2016

现在就是去除这个概念,egg 本身来说也只是集合插件,增加默认配置,和框架无异。而插件功能应该独立,会依赖一些框架 api(使用哪些 api 由被哪些框架依赖决定),但不应该覆盖。

@gxcsoccer
Copy link
Contributor

我一下子想不到具体的场景,但是插件覆盖 egg 的场景肯定是有的。比如: egg 内置了一些功能,我开发了一个插件做了新的实现或者依赖某些功能的开启或关闭,是有可能对 egg 配置做调整的

@popomore
Copy link
Member

popomore commented Aug 3, 2016

覆盖 egg 应该框架来做,插件只是使用 api

@dead-horse
Copy link
Member

指的是现在不允许插件覆盖 egg 或者框架定义的东西?

@gxcsoccer
Copy link
Contributor

gxcsoccer commented Aug 3, 2016

覆盖 egg 应该框架来做,插件只是使用 api

这个步子迈的有点大,而且是否合理呢? 我认为能在插件里做掉的,就不要抛到 framework 里了

@popomore
Copy link
Member

popomore commented Aug 3, 2016

我觉得是合理的,现在的 egg 更薄了,那在这之上的(比如内部使用版本)肯定是无法被插件覆盖的,所以尽量保持上面的原则。

@gxcsoccer
Copy link
Contributor

我理解 egg 是基线,plugin 是一堆扩展,framework 是最佳实践,app 是实际落地场景。

对于插件来说,最好的使用体验就是引入以后开启就好

@popomore
Copy link
Member

popomore commented Aug 3, 2016

就是引入开启就好

  1. 提供 api
  2. 有必要使用框架和其他插件的 api,但不应该覆盖

@gxcsoccer
Copy link
Contributor

额,@popomore 你说的是最理想的情况,有些插件不光是提供 api,他可能依赖一些底层的能力(这些能力可能是需要通过配置来开启或者调整参数的)。

从逻辑上讲,插件是“插”在 egg 上的,现在加载顺序,egg 在 plugin 后面,plugin 往哪儿插呢?

@popomore
Copy link
Member

popomore commented Aug 3, 2016

是的,但是这个本身不是 loader 文件做的,是在 app.js 自定义的,现在也是这样实现的。

@popomore
Copy link
Member

popomore commented Aug 3, 2016

egg 的加载有两层切面,一个是现在说的顺序,另一层是各个模块(middleware, service, extend 等)。模块之间会有顺序,每个模块则是按上面的顺序加载。所以这里的顺序只是决定加载同名文件时的覆盖顺序,app.js 则是灵活的,所以叫 customApp。

@gxcsoccer
Copy link
Contributor

gxcsoccer commented Aug 3, 2016

你的意思是:插件要覆盖 config,需要 app.js 里通过修改 app.config 来做?

还是说就不能覆盖?

@popomore
Copy link
Member

popomore commented Aug 3, 2016

现在大部分也是这么做的

@gxcsoccer
Copy link
Contributor

app.config ? 这个。。。为什么要这样呢

@popomore
Copy link
Member

popomore commented Aug 3, 2016

有业务场景才需要,不希望这样改。

比如在某个环境默认使用某些值,不希望被开发者覆盖,这时就需要修改 config

@popomore
Copy link
Member

popomore commented Aug 3, 2016

loadHelperEextend 感觉可以移到 egg 里,依赖 app.Helper

@popomore
Copy link
Member

popomore commented Aug 3, 2016

讨论的新结果是将 egg-loader 转成 egg-core,「一个带加载功能的 koa」。egg-core 保留 loader 功能,增加 constructor,初始化且加载。

这个 issue 等下更新下。

@popomore popomore changed the title loader 重构 egg-core Aug 3, 2016
@popomore
Copy link
Member

popomore commented Aug 9, 2016

  app.messenger.on('log-reload', () => {
    loggers.reload('got log-reload message');
    loggers.coreLogger.info('[egg:logger] logger reload: got log-reload message from self');
  });

这段逻辑放 logrotator?

@fengmk2
Copy link
Member

fengmk2 commented Aug 9, 2016

@popomore 方便,更加合适在 logrotator 插件,要不然还得约定 log-reload message

@popomore popomore modified the milestone: v1.x Aug 13, 2016
@popomore
Copy link
Member

#51

@popomore
Copy link
Member

#52

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants