业余插件作者案例研究

2024 年,我正在寻找工作。我决定提供自己作为 社区顾问 的服务。不过,大多数时候,人们更感兴趣的是获得技术帮助,以修复或更新他们的 Discourse 站点。一位潜在客户问我能否添加一个联系表单,让没有账户的人也能提交反馈。我四处查看后得出结论,这 不可行。但我当时有很多空闲时间,于是按照 插件开发教程 尝试看看能做成什么。最终,我开发了一个 联系表单插件,并成功签下了这位客户。[1]

为了让大家都清楚:我不是前端程序员! 距离我最后一次以程序员身份工作已经过去了 13 年。我只知道如何制作 HTML 表单,这就是我的全部知识范围。因此,我在 教程中的 Ember 和 Handlebars 部分 艰难前行,拼凑出了一个勉强能用的 hack 方案。幸运的是,由于我曾在 之前的工作中使用过模板系统,所以对这类系统并不陌生。

后来我加入了 OpenSSL 基金会[2],基本放弃了其他客户。但我之前为之开发插件的那位客户因为非常认可我的工作,一直将我保留在顾问名单上。(我为他做过几个无关的项目。)为了赚取顾问费,我决定升级他的 Discourse 服务器。结果我看到了以下内容:

这个错误只出现在我的客户网站上,因为我当时犯了一个愚蠢的错误:在 我的测试环境 上安装但未启用该联系插件。于是我迅速 进入安全模式 并禁用了该插件。上周末,我花了一些时间弄清楚问题出在哪里,以及如何为客户修复它。

经过一番搜索,我找到了 弃用主题和插件中的 .hbs 文件扩展名 这篇文章:

在最新版本的 Discourse 中,在主题和插件中使用 .hbs 文件已被弃用。在下一个 ESR 版本发布后,将不再支持该文件格式。

这条消息发布于三月,这意味着如果我使用的是 ESR 版本,我本应拥有直到九月底的时间来修复问题。但我的 Discourse 配置使用的是“tests-passed”[3],所以我提前几个月就遇到了这个错误。

既然无论如何我都得修复它(否则就会让客户失望),我便按照 自动将主题和插件更新为 .gjs 文件格式 的说明开始操作。第一步是 安装开发环境,因为自 上次尝试 以来,我已经更换了笔记本电脑。[4] 当我终于让 Discourse 运行起来,并确认插件在本地确实无法工作时,我运行了 lint 检查[5]

$ pnpm eslint --fix .

/Users/jericson/src/discourse-contact-plugin/assets/javascripts/discourse/components/contact-form.js
   1:8   error  Use Glimmer components(@glimmer/component) instead of classic components(@ember/component)          ember/no-classic-components
   3:16  error  Native JS classes should be used instead of classic classes                                         ember/no-classic-classes
   3:16  error  Please switch to a tagless component by setting `tagName: ''` or converting to a Glimmer component  ember/require-tagless-components
  20:3   error  Use the @action decorator instead of declaring an actions hash                                      ember/no-actions-hash

✖ 4 problems (4 errors, 0 warnings)

虽然不得不修改插件令人烦恼,但 lint 检查至少帮助我清理并现代化了我的代码。然而,自动化脚本在尝试转换为 .gjs 格式时失败了。于是,我决定试试 https://ask.discourse.com/。

我在那里提了 12 个问题。如果面对的是真人,我绝不会分享这些问题,因为它们只是一个越来越沮丧的程序员的胡乱挣扎。有一次,机器人建议我用一种“更健壮的现代方法”来解决我的某个子问题,结果却包括了一个 .js 文件和一个 .hbs 文件。

电影《八部半》中的一帧,导演将影评人对《八部半》的负面评价扔掉了。

我知道为什么会发生这种情况。它是基于 Meta Discourse 的讨论进行训练的,而其中仍有许多帖子包含 Handlebars 代码,包括 官方插件开发教程的第二部分。这些内容会随着时间的推移得到更新,但我担心这需要更长时间,因为 官方建议 是向聊天机器人求助,而不是在 Meta Discourse 上提问。

我想我不该抱怨;它确实帮助我理清了代码,而且可能比向真人求助更顺畅。

平台稳定性

我现在为 OpenSSL 基金会工作。你可能因为 Heartbleed 而听说过 OpenSSL。它被广泛使用。最受欢迎的下载版本是 1.1.1,该版本 已于 2023 年停止支持。其次是 3.0 版本,于 2021 年发布,但 仍作为长期支持(LTS)版本得到支持。接下来是 3.5 版本,这是我们最新的 LTS 版本。这三个版本几乎占 GitHub 下载量 的三分之二。

这有点令人失望,因为 3.5 版本有一些很酷的新功能。但归根结底,人们最关心的功能无非是 SSL/TLS加密原语 的组合。除非你对后量子加密算法感到兴奋,否则你会尽可能推迟升级的痛苦。

当然,OpenSSL 在技术栈中的位置比 Discourse 低得多。但原则是相同的。除非有新功能,否则人们并不热衷于破坏性的升级。我知道你们对 Discourse 新增的功能感到兴奋。我理解想要 为了后续优化而更改 API 的想法。我只是担心,推进速度过快会损害 Discourse 作为社区构建平台的稳定性。

说到这一点,有一份非常有用的演示文稿叫 平台园艺,由 Alex Komoroske 撰写。第 90 页开始了一个名为“平台 + 生态系统”的部分,解释了平台必须与其生态系统共同进化。在这种情况下,Discourse 是平台,它支持一个由插件和主题设计师、托管服务、Meta Discourse 社区以及建立在 Discourse 上的社区组成的生态系统。演讲者笔记中第 98 页有一个重要的见解:

但它们并非独立存在;它们是共生关系。

一个地方发生的行为会影响另一个地方,反之亦然。可以将其视为连接两者的双向反馈回路。

它们并非 rigidly 绑定在一起,更像是一条连接它们的橡皮筋。这是一种引力。

如果平台和生态系统相对于彼此移动过快,这种纽带就会断裂,造成灾难性后果。我信任 Discourse 会善待其生态系统。只是像上周末那样的事件让我对这份信任产生了动摇。


  1. 尽管最终它只是一个 相当静态的网站,但我对自己的工作还是相当自豪。 ↩︎

  2. 伏笔! ↩︎

  3. 这也需要 更新 ↩︎

  4. Redis 和 Rails 的安装比我记忆中要困难得多。 ↩︎

  5. 不过在此之前,我花了很多时间却没能成功 获取 eslint.config.mjs ↩︎

我认为你遇到这个错误是因为这个漏洞,而不是因为你的插件现在需要更新:

我也遇到过很多自己编写的插件面临同样的问题。我没有足够的时间和精力将它们现代化到符合 Discourse 标准的程度。我的工作是数据科学类的,虽然我了解软件工程的概念,但无法持续跟进 Web 开发的具体细节。最终,由于这些插件已废弃,我的网站整整八个月没有更新。

我不想轻视你的困境,但基本上我认为,随着代理式编程(agentic coding)的出现,这种开发速度问题已不再是难题。原本需要我花一两周时间编写并调试正确的功能,现在只需花费 20 美元的 Claude Code 订阅费,每个插件仅需几分钟即可完成。不仅如此,我还能够优化它们的性能。在将代理式编程应用于几个工作和业余项目后,我认为我余生都不会再从零开始编写任何代码了。这就像手写并投递信件与发送邮件之间的技术差异。虽然有点令人伤感,但同时也感觉仿佛被赋予了神一般的能力。

确实很有可能。升级到最新的 ESR 版本(并且在测试时更加谨慎)似乎是从今往后的好计划。

我不认为开发速度本身是个问题。问题在于“一切”的速度。例如,为什么 插件教程 还没有更新?它就像一颗随时可能炸毁那些想构建插件的倒霉蛋的定时炸弹。目前它还能用,但最终他们会遇到和我一样的问题。解决办法不是以后用 AI 来修复插件,而是现在就修正关于制作插件的说明。我的意思是,没有理由继续教授旧的方法,对吧?

因为我们是一个相对较小的团队,既要维护庞大的代码库,又要为付费客户实现新功能,同时还要为开源社区提供支持并确保一切正常运行。

我们每天能做的事情有限,文档往往因此滞后。

我非常理解您的沮丧,但我觉得这一点也值得提及。

感谢提供详细信息,@jericson。正如你所说,Discourse 在用途和架构层级方面与 OpenSSL 处于截然不同的位置。这是一个在进步、可定制性和稳定性之间不断权衡的过程。并不存在能让所有人都满意的完美方案,但我们始终将来自客户和开源社区的反馈纳入考量。我非常喜欢你分享的那段话:

:chefs_kiss:

正如 @moin 提到的,你遇到的 .hbs 弃用问题在 latest 版本中是一个持续约一周的 bug。对此我们非常抱歉!虽然 .hbs 的使用已被弃用,但仍受支持。你的 .hbs 代码现在应该可以正常运行了。

感谢指出这一点。我已经着手清理文档中剩余的 .hbs 相关内容:

完全理解。[1]非常喜欢 Discourse,我写这篇帖子是因为我希望 Discourse 能够持续取得成功。

我学到的一点是,社区并不喜欢变革,但如果他们感觉自己拥有自主权,就会对变革更加开放。赋予人们自主权的方式有无数种。例如,可以将教程改为 维基帖子,这样像我这样的人就可以更新它们。实施 ESR 计划也有帮助,因为它让人们可以选择暂不立即进行更改。[2] 能够写下我的经历并让管理开源项目的人看到,也很有帮助。尤其是因为我抱怨的问题在一夜之间就得到了解决。:wink:

在《倾听用户是否有害?》一文中,[3] Kathy Sierra 写道:

我们大多数人都意识到,焦点小组在许多方面 notoriously 无效,但我们仍然假设倾听真实用户的真实反馈是推出新产品和服务以及改进现有产品的最佳方式。但这存在一个巨大的问题——人们未必知道如何提出他们从未设想过的需求! 大多数人提出的建议完全基于_渐进式_改进,着眼于现有内容并思考如何使其更好。但这与拥有某种全新事物的愿景截然不同。

真正的创新很少会直接来自用户所说的话。

正如我所说,我不是前端开发人员。我不太明白为什么会有这些更改,也不清楚它们将如何使我受益。[4] 如果这些更改最终能让 Discourse 变得更好,那也没关系。

不过,如果我能更清晰地看到愿景,就能帮助像我这样的人更好地接受这些变化。对于 这项更改,其宣传点是:

  1. 更佳的开发体验
  2. 将为未来版本的 Discourse 带来显著的性能提升

听起来不错,是吧?我并没有特别注意到第 1 点和第 2 点可能包含多种含义。对我来说,更有效的方式可能是(我完全是凭空想象的):

  1. 在转换官方 Discourse 插件时,我们发现这减少了 X% 的代码行数。将模板与 JavaScript 放在同一文件中,使得代码更易于理解和修改。
  2. 我们设置了一个分支,测试完全移除 Handlebars,发现这一更改使页面加载速度提升了 X%。不仅如此,我们还发现了一种潜在的优化方案,可以解决 [用户提出的一些问题]。

多一些细节,并着眼于教育非专家,对于维持信任大有裨益。我可能不喜欢这些更改,但面对其他用户实际遇到的问题,我又怎能反驳呢?


  1. OpenSSL 也有类似的动态。我们有一个公司(约 15 人)负责销售支持合同,还有一个基金会(10 人,包括我在内)负责非商业利益。我们的文档也存在滞后问题。在撰写原帖时,我发现其中仍引用了上个月已移除的功能。我正在为此提交一个 PR。此外,我们还进行了一些更改,这些更改受到了 下游 项目 的高度批评。 ↩︎

  2. 对于希望支持那些希望紧跟前沿的社区的插件作者来说,这帮助不大。但对我而言这将非常有益,因为我相信我是唯一使用我的插件的人。 ↩︎

  3. 她的博客已从互联网上消失,但这里有一份 PDF 存档↩︎

  4. 这并不是说我在大局中多么重要。我所说的“我”只是代表其他依赖 Discourse 的人。毕竟,我比大多数人更了解自己! ↩︎

为什么这需要是 Wiki 呢?开发者文档是通过 GitHub 管理的。我更喜欢这种变更经过审查的流程,甚至优于 Wiki。

我同意,此时确实应该更新插件文档。“弃用”期的目标是在插件仍可运行但网站会发出即将失效的警告时,为插件作者留出足够的时间进行修复。然而,在这段期间内,即使是一支全职的付费开发团队也无法及时更新核心插件开发文档。在团队都难以在相同时间内完成的情况下,却对个体开发者提出这样的要求,实在有些不合常理。

这在我看来,说明开发速度过快,或者插件作者并非 Discourse 的优先关注对象。就我个人而言,更倾向于后者。我理解某些方面难免需要被搁置,因此这更多是我的观察,而非批评。Discourse 依然可以通过插件实现完全自定义,我也很感激其持续不断的改进。

话虽如此,我认为我们已处于这样一个节点:逐步式的插件构建指南已显得过时。如今,对于业余插件作者而言,只需一份供智能体阅读并生成插件骨架的上下文文档就足够了。事实上,对于像 Discourse 这样的开源代码库,甚至根本不需要文档,因为智能体可以直接从代码库本身获取上下文。在我开发插件的过程中,我看到 Claude 通过阅读现有插件来学习设计模式。我甚至借此在核心代码中发现了一个 bug:Chat Pitchfork timeouts: replies silently create threads and auto-tracking bloats over time

总之,对于任何有志成为业余插件作者的读者来说,尽管文档可能已过时,但如今构建插件的难度比以往任何时候都低了上千倍。

对此稍作澄清:hbs 的弃用时间线 才刚刚开始。我们最早考虑停止支持的时间是在下一个 ESR(长期支持版)之后,即 7 月底。因此,我们确实应该更早更新文档,但这并非“在未给予足够警告的情况下停止支持”的情况。.hbs 目前仍受支持,并且有充足的时间进行必要的更改。

我们维护着 600 多个主题和插件,因此我可以向您保证,我们也深切体会到这些迁移带来的“痛苦”。我们尽最大努力让每个人的变更过程尽可能顺畅,并将继续从每次变更中吸取经验。

:100: 没错

我们目前尚未完全实现这一点。但我们正在核心仓库中逐步建立一个 技能 目录。此外,所有开发者文档的 Markdown 文件已移至核心仓库,部分原因是为了让 AI 代理更易于引用。

我可能把一些事情搞混了,因为我在修复插件以适配 Ember 6 升级(这是我面临的主要更新障碍)的同时,也一并完成了从 hbs 的迁移。如果我之前过于武断,还请见谅!

不过,如果 Discourse 确实希望壮大用户自制的插件生态系统,那么一份现代化的“vibecoding”教程将会很有帮助。但话又说回来,是否应该打开闸门,让一波“vibecoded”插件涌入呢?这很难说 :smile:

啊!这很有帮助。已提交拉取请求。

我支持将文档放在 GitHub 上。虽然提交变更比编辑维基帖子要费事得多,但审核步骤非常有用。(而且对于插件作者文档来说,要求掌握 Git 并不算门槛太高。)