# 业余插件作者案例研究

**URL:** https://meta.discourse.org/t/case-study-of-an-amateur-plugin-author/402084
**Category:** Development
**Created:** [2026年五月3日 03:41 UTC](https://meta.discourse.org/t/case-study-of-an-amateur-plugin-author/402084 "2026-05-03T03:41:19Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![jericson](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jericson/32/116215_2.png) [@jericson](https://meta.discourse.org/u/jericson)
#### Post date: [2026年五月3日 03:41 UTC](https://meta.discourse.org/t/case-study-of-an-amateur-plugin-author/402084/1 "2026-05-03T03:41:19Z")

</div>

2024 年，我正在寻找工作。我决定提供自己作为 [社区顾问](https://buildcivitas.com/) 的服务。不过，大多数时候，人们更感兴趣的是获得技术帮助，以修复或更新他们的 Discourse 站点。一位潜在客户问我能否添加一个联系表单，让没有账户的人也能提交反馈。我四处查看后得出结论，这 [不可行](https://meta.discourse.org/t/contact-form-without-third-party-services/233273)。但我当时有很多空闲时间，于是按照 [插件开发教程](https://meta.discourse.org/t/developing-discourse-plugins-part-2-connect-to-a-plugin-outlet/31001) 尝试看看能做成什么。最终，我开发了一个 [联系表单插件](https://meta.discourse.org/t/contact-form/305462)，并成功签下了这位客户。\[1\]

为了让大家都清楚： **我不是前端程序员！** 距离我最后一次以程序员身份工作已经过去了 13 年。我只知道如何制作 HTML 表单，这就是我的全部知识范围。因此，我在 [教程中的 Ember 和 Handlebars 部分](https://meta.discourse.org/t/developing-discourse-plugins-part-2-connect-to-a-plugin-outlet/31001) 艰难前行，拼凑出了一个勉强能用的 hack 方案。幸运的是，由于我曾在 [之前的工作中使用过模板系统](https://github.com/EnterpriseDB/docs/blob/develop/install_template/README.md)，所以对这类系统并不陌生。

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

 ![加载插件 discourse-contact-plugin 失败，来源为 http://localhost:4200/assets/js/plugins/discourse-contact-plugin_main-r9hlw1h8.digested.js 错误：找不到从 (require) 导入的模块](https://global.discourse-cdn.com/meta/original/4X/b/7/1/b71c3be885137979eb87a4ac97ad37a9b958f992.png)

这个错误只出现在我的客户网站上，因为我当时犯了一个愚蠢的错误：在 [我的测试环境](https://beta.buildcivitas.com/t/staging-server-for-discourse-hosting/112) 上安装但未启用该联系插件。于是我迅速 [进入安全模式](https://meta.discourse.org/t/using-safe-mode-to-troubleshoot-issues-with-themes-and-plugins/53504) 并禁用了该插件。上周末，我花了一些时间弄清楚问题出在哪里，以及如何为客户修复它。

经过一番搜索，我找到了 [弃用主题和插件中的 .hbs 文件扩展名](https://meta.discourse.org/t/deprecating-hbs-file-extension-in-themes-and-plugins/398896) 这篇文章：

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

这条消息发布于三月，这意味着如果我使用的是 [ESR 版本](https://meta.discourse.org/t/rfc-a-new-versioning-strategy-for-discourse/383536)，我本应拥有直到九月底的时间来修复问题。但我的 Discourse 配置使用的是“tests-passed”\[3\]，所以我提前几个月就遇到了这个错误。

既然无论如何我都得修复它（否则就会让客户失望），我便按照 [自动将主题和插件更新为 .gjs 文件格式](https://meta.discourse.org/t/automatically-updating-themes-and-plugins-to-gjs-file-format/368051) 的说明开始操作。第一步是 [安装开发环境](https://meta.discourse.org/t/install-discourse-on-macos-for-development/15772)，因为自 [上次尝试](https://jlericson.com/2022/10/24/discourse_theme-1.html) 以来，我已经更换了笔记本电脑。\[4\] 当我终于让 Discourse 运行起来，并确认插件在本地确实无法工作时，我运行了 lint 检查\[5\]：

```plaintext
$ 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/。](https://ask.discourse.com/%E3%80%82)

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

[![电影《八部半》中的一帧，导演将影评人对《八部半》的负面评价扔掉了。](https://global.discourse-cdn.com/meta/original/4X/a/b/f/abf0e4c01b7dbcf8c8641a02448442457b22fbde.png)](https://jlericson.com/2023/06/26/problem_ai.html)

我知道为什么会发生这种情况。它是基于 Meta Discourse 的讨论进行训练的，而其中仍有许多帖子包含 Handlebars 代码，包括 [官方插件开发教程的第二部分](https://meta.discourse.org/t/developing-discourse-plugins-part-2-connect-to-a-plugin-outlet/31001)。这些内容会随着时间的推移得到更新，但我担心这需要更长时间，因为 [官方建议](https://meta.discourse.org/t/deprecating-hbs-file-extension-in-themes-and-plugins/398896) 是向聊天机器人求助，而不是在 Meta Discourse 上提问。

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

## 平台稳定性

我现在为 OpenSSL 基金会工作。你可能因为 [Heartbleed](https://openssl.foundation/news/my-talk-at-fosdem-2026) 而听说过 OpenSSL。它被广泛使用。最受欢迎的下载版本是 1.1.1，该版本 [已于 2023 年停止支持](https://openssl-library.org/post/2023-09-11-eol-111/)。其次是 3.0 版本，于 2021 年发布，但 [仍作为长期支持（LTS）版本得到支持](https://openssl-library.org/roadmap/index.html)。接下来是 3.5 版本，这是我们最新的 LTS 版本。这三个版本几乎占 [GitHub 下载量](https://openssl-library.org/source/) 的三分之二。

这有点令人失望，因为 [3.5 版本有一些很酷的新功能](https://openssl.foundation/news/the-features-of-3-5-quic-server)。但归根结底，人们最关心的功能无非是 [SSL/TLS](https://docs.openssl.org/master/man7/ossl-guide-libssl-introduction/) 和 [加密原语](https://docs.openssl.org/master/man7/ossl-guide-libcrypto-introduction/) 的组合。除非你对后量子加密算法感到兴奋，否则你会尽可能推迟升级的痛苦。

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

说到这一点，有一份非常有用的演示文稿叫 [平台园艺](https://docs.google.com/presentation/d/1cY95dRixFho0pMIlrEFcGL_XKVy9vnE4NGOD6TQMj50/edit?usp=sharing)，由 [Alex Komoroske](https://www.komoroske.com/) 撰写。第 90 页开始了一个名为“ **平台 + 生态系统** ”的部分，解释了平台必须与其生态系统共同进化。在这种情况下，Discourse 是平台，它支持一个由插件和主题设计师、托管服务、Meta Discourse 社区以及建立在 Discourse 上的社区组成的生态系统。演讲者笔记中第 98 页有一个重要的见解：

> 但它们并非独立存在；它们是共生关系。
> 
> 一个地方发生的行为会影响另一个地方，反之亦然。可以将其视为连接两者的双向反馈回路。
> 
> 它们并非 rigidly 绑定在一起，更像是一条连接它们的橡皮筋。这是一种引力。

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

* * *

1. 尽管最终它只是一个 [相当静态的网站](https://www.evansmechanicalservices.com/)，但我对自己的工作还是相当自豪。 

2. 伏笔！ 

3. 这也需要 [更新](https://meta.discourse.org/t/tests-passed-is-now-latest/384272) 

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

5. 不过在此之前，我花了很多时间却没能成功 [获取 `eslint.config.mjs`](https://meta.discourse.org/t/automatically-updating-themes-and-plugins-to-gjs-file-format/368051/11?u=jericson)

---

_[View the full topic](https://meta.discourse.org/t/case-study-of-an-amateur-plugin-author/402084)._
