将Discourse插件打包成gem

Pavilion 已开始将一些 Discourse 插件打包成 Ruby gems,首先是我们的订阅客户端。

我们的订阅客户端仍然是一个单独的插件,现在加载这个 gem,但它的后端现在完全打包成了一个 gem,并且该单独的插件将很快被完全弃用。这是一个关于如何为更适合打包成 gem 的插件做同样事情的简要介绍。

如何使用 gem

首先,你需要了解如何使用 Ruby gems。如果你以前从未创建过 gem,我建议你在尝试将 Discourse 插件作为 gem 处理之前,先单独创建自己的标准 gem。我推荐这篇指南:

插件如何将代码注入 Discourse

Discourse 插件 gem 将代码注入 Discourse 的方式与标准插件完全相同。唯一的区别在于打包方式。因此,要将插件作为 gem 来处理,你还需要了解标准插件是如何将代码注入 Discourse 的。这里基本上有两个需要理解的地方:

  1. Discourse 插件是一个 Rails 引擎。你可能已经知道了这一点,但你需要真正理解它的含义。我建议你阅读这篇关于 Rails 引擎的指南。例如,你需要理解为什么 Discourse 插件的 plugin.rb 文件中的很多代码都包装在 after_initialize 回调中。

  2. Discourse 的初始化过程是如何工作的。这里只有一个文件需要阅读和理解,那就是 discourse/discourse/config/application.rb 文件。在那里,大部分 Rails 代码被加载,所有插件代码被加载,插件被初始化。深入阅读该文件,理解插件文件在何处以及如何被引入和初始化。

Discourse 插件作为 gem 如何工作

为了将以上内容结合起来,你还需要理解上述两个主题是如何在 Discourse 插件 gem 中合成的。特别是要注意以下几点:

  1. 在 Discourse 插件 gem 中,engine.rb 文件扮演着与 plugin.rb 文件类似的角色,但有一些配置上的差异。查看订阅客户端 gem 的 engine.rb 文件,并将其与标准的 plugin.rb 文件进行比较。

  2. 在 Discourse 插件 gem 中,你需要在 rspec 测试中模拟 discourse/discourse 才能正确测试 gem。你不必模拟整个 Discourse 应用,只需模拟你正在测试的部分。你可以通过创建一个骨架 Rails 应用,包含你需要的特定 Discourse 类和端点,并将其加载为 rspec 支持。请参阅订阅客户端 gem 的模拟 Discourse 应用,以及它在 spec rails_helper.rb 中的加载位置。

如何在 Discourse 插件中加载本地 gem

要在开发过程中处理该插件和 gem 时,在 Discourse 插件中加载 gem 的本地版本,你需要执行以下操作:

将你的 gem 文件夹链接到相关插件的 gem 文件夹。例如,要在 discourse-subscription-client 插件中处理 discourse_subscription_client gem 的本地版本,我执行以下操作:

ln -s /Users/angus/discourse/gems/discourse_subscription_client /Users/angus/discourse/discourse/plugins/discourse-subscription-client/gems/3.2.1/gems

然后更改插件中链接的 gem 文件夹,使其使用与标准 gem 文件夹相同的名称模式,例如:

discourse_subscription_client-0.1.0.pre11

现在,当你的插件加载你的 Discourse 插件 gem 时,它将加载你的本地版本,而不是rubygems 上的版本。

如果你有任何问题或遇到困难,请在此处发帖,我会帮助你。

14 个赞

看起来这种方法无法涵盖插件中的任何 Discourse 主题内容?也许更好的标题是“将特定于 Discourse 的 Rails 引擎打包成 gem”

1 个赞

这是正确的,您需要单独处理前端 JS 框架。

虽然技术上准确,但我不同意这个标题会更好,因为这会吓跑一些合适的人:大多数编写插件的人可能不会将它们识别为“特定于 Discourse 的 Rails 引擎”。

我现在实际上更经常地将我的代码分离为后端插件和前端主题组件,这样我就可以在部署到暂存和生产环境时非常快速地迭代前端内容。

3 个赞

我同意这一点,尽管这份文档可能只对一些高级开发人员有用,但它应该涵盖所有人。

感谢分享。

1 个赞

同意这是一个高级主题。