为自托管者引入预编译的 JS 资源

:mega: Discourse 现在会发布预编译的 JavaScript 资源文件,这将显著加快安装和更新速度,特别是对于资源有限的服务器。


编译和优化 JavaScript 资源文件一直是运行 Discourse 最耗费资源的部分之一。随着我们的代码库和 JavaScript 生态系统的发展,这个过程变得更加苛刻。

在我们的测试中,这些更改将一台 1GB 内存的 Digital Ocean 虚拟机的资源构建时间从 45 分钟缩短到仅 3 分钟。

它是如何工作的?

每当有提交合并到 main 分支时,一个 GitHub Actions 工作流 就会将资源文件构建并打包成 .tar.gz 文件(一个用于生产环境,一个用于开发环境)。这些包通过 GitHub Releases 发布,存放在一个专门的仓库中。我们确保在任何提交移至 tests-passed 之前发布这些资源文件。

在构建您自己的站点时,Discourse 现在会检查是否存在匹配的预编译包并下载它。然后在此基础上构建插件。如果找不到包或出现错误,Discourse 会回退到从源代码构建。

这会影响最终用户吗?

不会。资源文件仍然从您自己的服务器/CDN 提供给最终用户。

我可以退出吗?

可以!如果您希望自己构建资源文件,并且拥有足够强大的服务器,请在 app.yml 文件中将 DISCOURSE_DOWNLOAD_PRE_BUILT_ASSETS 设置为 0

如果我运行的是 Discourse 的分叉或已修补的版本怎么办?

资源包是根据提交哈希命名的。如果您运行的是一个分叉版本,将找不到任何包,资源文件将从源代码构建。如果您的 Discourse 副本已修补(即 git 工作目录不干净),Discourse 将不会尝试下载包。

其他与资源相关的构建步骤呢?

目前,此优化仅适用于核心 JS 资源文件。未来,我们可能会将其扩展到某些插件和其他步骤,如 gz/brotli 压缩。

稳定分支呢?

稳定分支的预编译资源文件将在下一个主要版本更新后发布,计划于 2025 年 8 月进行。

53 个赞

我刚刚重建了 https://discourse-on-a-pi5.falco.dev/,仅用了 3 分 35 秒,这非常令人印象深刻!

23 个赞

两个容器设置,无数据库,大约需要 8 分钟。

5 个赞

:scream: :person_bowing:

我的配置中没有这个选项,我需要添加一个值为 1 的选项才能选择加入吗?或者下次更新时这一切都会自动发生?

FYI,当您的安装不符合标准时,会发生以下情况:

I, [2025-08-01T06:43:09.560655 #1]  INFO -- : cd /var/www/discourse & su discourse -c 'bundle exec rake assets:precompile:build'
[assemble_ember_build] Node.js heap_size_limit 小于 2048MB。正在设置 --max-old-space-size=2048 和 CHEAP_SOURCE_MAPS=1
[assemble_ember_build] 未找到现有的 build info 文件。
[assemble_ember_build] Git 工作目录不干净。无法下载预构建的资源。
[assemble_ember_build] 正在运行完整的核心构建...

我正在对 app.yml 中的 config/initializers/100-sidekiq.rb 进行一些调整,以支持所有 sidekiq 作业的重试计数(我猜这是实现此目的的唯一方法,而不是在插件中?但可以重新审视),因此我认为这足以不符合标准……

2 个赞

默认情况下已启用。您只需要指定配置即可选择退出。

是的,没错。任何对 git 存储库的更改都会导致它退出。

关于 sidekiq 的问题,如果您就此开设一个主题,我相信我们可以通过插件或其他方式来解决,或者我们可以为其引入一个新的 GlobalSetting

4 个赞

顺便说一句,一种非常简单的计时构建而无需留在控制台前的方法是:

time ./launcher rebuild app
11 个赞

不错的改动。我得到了

real 2m41.898s
user 0m0.372s
sys 0m0.583s

感谢您的工作。

4 个赞

哇,令人印象深刻。已定义日期吗?我的版本是 a81eaacb1c53581912519ae6574fa3523ef215dd,我应该等待重建吗?

哦,太棒了 :star_struck:

感谢 @merefield - 真不敢相信我 7 年来进行了数百次命令行重建,现在才发现这个 :grin:

5 个赞

如果您遵循我们的标准发布渠道,您可以立即重建并从中受益。

4 个赞

唯一的!谢谢。

1 个赞

4分钟即可重建,我今天已经完全迁移了几次!令人印象深刻的 Discourse!下次重建时,我会记得使用那个漂亮的命令,谢谢大家。

1 个赞

也许可以将此限制在核心和插件的 app/assetsconfig/locales 中?目前,当应用了仅 Ruby(安全)的补丁时,这也会导致完全重建。

是的,我们有可能进一步限制。尽管对于安全补丁来说,它们很可能会影响到 JS 应用,因此仍然需要进行完全重建。

2 个赞

试了一下,太棒了,大约 3 分钟!真是个聪明又了不起的功能。:star_struck:
这让我现在想一个接一个地安装所有现有的插件。:rofl:

5 个赞

真的真的,太棒了

实际上,我认为这会适得其反,如果我理解正确的话。

你看,它只能使用已捆绑核心代码的已编译资源(这在很大程度上解释了最近捆绑流行核心插件的决定!)

它必须在构建过程中构建和捆绑任何“未知”插件,因此其中许多插件会大大减慢它的速度。

2 个赞

更新到 3.6.0.beta1 时找不到预构建的资源

正在获取并解压 https://get.discourse.org/discourse-assets/3.6.0.beta1-d63a2431/production.tar.gz...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100     9  100     9    0     0     24      0 --:--:-- --:--:-- --:--:--    24
curl: (22) 请求的 URL 返回错误:404
[assemble_ember_build] 下载预构建资源失败:命令失败,退出代码 22:curl
[assemble_ember_build] 正在运行完整的核心构建...

2 个赞

您是在为此次安装定位 beta 标签吗?