适用于 v2.0.0。
-
分工
core
只涉及核心功能,不考虑命令行界面等,不能引用任何plugin
。util
尽量为纯函数,可单独测试,不能引用core
或plugin
。
-
配置文件
-
core
内部模块不引入配置文件,而是把选项设计为参数。 -
在最表层引入配置文件。
-
配置文件(理论上)可被命令行参数替代。
-
plugin
可以向配置文件中添加自己的键,但仍用core
读取config
。# config.yml ding: # plugin/ding 的配置 secrets_path: config/ding.secrets.yaml
配置的具体规定目前只加入
config/config.schema.json
,不加入src/core/config.ts
。
-
-
core
中钩子core
内部模块通过参数_hook
传入hook
。- 在最表层
new Hook.Collection<HooksType>()
,并向外暴露hook.api
。
-
尽量模块化
- 隐藏模块内细节:
core
中每个文件夹都有index.ts
,外部一律引用它。
- 隐藏模块内细节:
可生成 mermaid .js 的 flowchart,如下图。
$ python scripts/import_graph_mod.py
flowchart LR
examples --> plugin/rss
examples --> plugin/proxy
examples --> plugin/ding
examples --> plugin/cli
examples --> util
examples --> core
plugin/proxy --> core
plugin/proxy --> util
plugin/rss --> core
plugin/cli --> util
plugin/ding --> core
plugin/cli --> core
plugin/rss --> util
core --> util
$ python scripts/import_graph_single.py core
flowchart LR
subgraph core
core/fetch_wrapper --> core/hooks_type
core/index --> core/config
core/sources --> core/fetch_wrapper
core/models --> core/hooks_type
core/index --> core/hooks_type
core/notices --> core/hooks_type
core/update_notices --> core/hooks_type
core/notices --> core/models
core/index --> core/update_notices
core/update_notices --> core/notices
core/sources --> core/models
core/sources --> core/hooks_type
core/update_notices --> core/sources
core/hooks_type --> core/models
core/index --> core/models
core/update_notices --> core/models
end
core/notices -.-> util/my_date
core/sources -.-> util/my_date
core/notices -.-> util/logger
examples/ding-cli -.-> core/index
examples/cli -.-> core/index
examples/rss-cli -.-> core/index
plugin/cli/util -.-> core/index
plugin/rss/index -.-> core/index
plugin/rss/rss -.-> core/index
plugin/ding/index -.-> core/index
plugin/cli/hooks -.-> core/index
plugin/proxy/index -.-> core/index
examples/proxy-cli -.-> core/index
# Turn on `case LinkType.absolute` in `generate_markdown` in advance.
$ python scripts/import_graph_single.py plugin/ding
flowchart LR
subgraph plugin/ding
plugin/ding/index --> plugin/ding/bot
plugin/ding/bot --> plugin/ding/sign
end
plugin/ding/index -.-> core/index
plugin/ding/index -.-> yaml
plugin/ding/sign -.-> crypto
plugin/ding/bot -.-> node-fetch
plugin/ding/index -.-> fs/promises
examples/ding-cli -.-> plugin/ding/index
classDiagram
class Notice {
+ link: string
+ title: string
+ date: Date | null
+ source?: Source
- #source_ref: Source | string
+ id: string
}
class Source {
+ name: string
+ full_name: string
+ alt_name: string[0..*]
+ url: string
+ guide: string[0..*]
+ id: string
}
Notice "0..*" -- "1" Source
我们使用 before-after-hook 的HookCollection
,请参考它的文档。
octokit.js 也使用了
HookCollection
,亦可作参考。
// 预留钩子示例
import type { HookCollection } from 'before-after-hook'
type HooksType = {
foo: {
Options: FooOptions
Result: FooResult
}
}
function _foo (options: FooOptions): FooResult {
// …
}
export function foo ({ _hook, ...options }: {
_hook: HookCollection<HooksType>
} & FooOptions): Promise<FooResult> {
return _hook('foo', _foo, options)
}
// 使用钩子示例
import { Hook } from 'before-after-hook'
const _hook = new Hook.Collection<HooksType>()
_hook.before('fetch', before_hook)
await foo({
...options,
_hook
})
插件可以在 before hook 中向options
添加自己的属性,供相应 after hook 使用。预留钩子时要避免把自定义属性传丢了。