关于对配置构型的疑问

我在阅读文档时,看到以下代码,这段代码一般在index.ts的开头


如果我想在另一个ts文件,比如test.ts文件中想读取到index.ts中foo的值,
通常创建一个函数fuc(config:Config){
console.log(config.foo)
}
来调用这个函数获得foo,

那么问题来了,如果这个函数需要被很多其他函数调用时,调用形式都是fuc(config)的形式,导致config这个参数在很多地方都必须声明
如何在test.ts文件中直接调用foo,不以函数参数的形式来调用
即能不能做到fuc(){
console.log(foo)
}
这样的效果

1 个赞

不能。

阿哲。

1 个赞

你的问题用最简单的话来说就是:

我现在有一个函数 add(a, b) { return a+b },如何在我不传入 a 和 b 的时候也能计算 ab 之和?

我觉得现代科技应该解决不了这个问题

我的问题是能不能把config放在函数外面,然后函数直接读取这样子

1 个赞

image
然后test函数不能添加参数config这样子

2 个赞


image
最终的效果应该是这个样子

1 个赞

没有区别吧,你现在想做的就是想在不传入参数的情况下获得参数吧

你如果能把这个 :point_up_2: 问题解决了的话那就能做到了

image
这样的效果呢,可以做到咩

1 个赞

image

1 个赞

你真要试试的话就会发现是可以的,但问题在你写完插件发布完之后才会逐渐出现。

举个例子,你写了一个直播监控插件监控 B 站和网易的主播是否开播,配置项非常简单,用户传入的对象类似:

{ bilibili: [6655], cc: [361433] }

你写了一个函数用来轮询直播间状态:

let myConfig

const startListen() {
  const [bilibili, cc] = myConfig
  setInterval(() => {
    bilibili.map(房间号 => fetch('B 站 API' + 房间号).then(返回值 => { /* 处理返回值 */ })
  }, 10000)
}

然后在你的插件里设置 config 并调用:

export function apply(ctx, config) {
  myConfig = config
  startListen()
}

这段代码能够正常运行,你能够正确拿到 B 站和网易的直播间,也能正确跟踪直播状态。

问题在插件发布以后:

  1. 用户修改了插件的配置并保存。但修改了插件的配置以后,不仅新的主播没有被添加进来,旧的主播的开播事件竟然会被发送两次;
  2. 用户创建了两个插件,准备给两个粉丝群分别推送两个不同的主播消息。但两个群不管怎么设置,推送的都是同一个主播;

诸如此类的 bug 会有很多,我就不一一列举了。Koishi 内的每个插件,以及每个插件内的每个对象都有其作用域和生命周期,目的在于保证每次使用插件时插件都执行正确的逻辑。

题外话,除了 Koishi 以外的一切 Bot 框架都支持直接从最外层环境获取所需的数据,只有 Koishi 不支持。这是因为其他框架均不支持插件的重载和复用,因此其他框架无需考虑配置的作用域和生命周期问题。插件在这些框架中只会存在一个实例,所以配置直接加载一个独立文件即可,任何文件内都可以直接读取配置文件里的数据。相对地,这些框架的插件开发者需要自行实现在不同环境下进行配置的功能。

举个例子,对于上文提到的「推送主播开播状态」这个需求,如果用户希望向两个群推送两个不同的主播,只需创建两个插件分别指定不同的群,两个插件便会携带着各自的配置分别对这两个群生效。除了群组以外,你还可以指定在特定的平台、特定的用户、或仅限私聊的情况下开启插件功能。在其他框架,你只能请求插件作者自行添加相同的功能。

1 个赞

错误的。Koishi 同样支持:

export const shared = {}

export function apply(ctx: Context, config: Config) {
  shared.config = config
}

支持从外层环境读取数据是语言特性,并非框架功能。不懂的如何从外层环境读取数据的话,建议学习 JavaScript 基本知识。

然而,任何现代应用程序都绝不应该从外层读取数据,这会造成楼上所说的毁灭性后果。之所以有「其他一切 Bot 框架都支持」的谬论,那是因为其他框架没有给用户提供解决方案,用户需要自己将数据封装好,避免泄漏到外层,而不是说泄漏到外层就是对的。

Koishi 致力于保护用户的数据安全。当你写出上面的代码时,你的插件将可能被标记为不安全。

1 个赞

先看完我的上一个回帖 :anger:

我只是单纯回复这句话,错误的。

1 个赞

你书得对