为插件引入新的构建系统

在过去的几个月里,我们一直在为插件的 JavaScript 代码构建一个新的构建系统。这将使插件与我们在 2025 年 7 月对主题构建系统所做的更新保持同步,这些更新更多地依赖于现代浏览器技术和 JS 构建工具。

此更改在很大程度上向后兼容。大多数插件作者无需进行任何操作。 :tada:

优势

除了幕后现代化之外,此更改还将为 Discourse 开发者和托管者带来许多功能上的优势:

  1. 插件资源被高度缓存,并且以每个插件为单位进行索引。这意味着在开发环境中重启服务器时,无需从头重新构建所有插件。

  2. 我们可以开始在 现有的资源包 中包含热门插件的预编译代码。在重新构建时,只需构建已更改或新增的插件。这对于资源受限的机器尤其有用。

  3. 插件代码将被转译为原生 ES 模块。这带来了更简洁的语法、在浏览器中更快的执行速度,并为未来使用 import() 等功能进行代码拆分铺平了道路。

测试 / 时间线

我们内部已测试该系统一段时间,并在数百个官方插件上验证了其功能。Meta 站点已使用新系统运行数周。

如果您想亲自尝试,可以设置环境变量 ROLLUP_PLUGIN_COMPILER=1

我们计划很快将默认值更改为新系统。如果出现任何意外情况,将会有一个短暂的时期允许使用 ROLLUP_PLUGIN_COMPILER=0 禁用新系统,但我们打算将过渡期保持在最低限度。

复杂插件可能遇到的问题

对于更复杂的插件,新系统在某些方面更加严格:

  1. 从非管理代码导入管理模块 现在将引发异常。这一直是不被推荐的,并且会导致令人意外的错误。现在,系统会更有针对性地检测并阻止此类操作。

    如果您遇到此问题,应考虑是否应将插件代码更好地放置在 admin-js 目录(admin/assets/javascripts/...)中。如果您确实需要条件性地导入管理模块,则应使用核心提供的 optionalRequire 辅助函数来实现。

  2. 跨插件导入 仍然受支持。然而,与管理模块类似,导入未安装或未启用的插件中的模块现在将引发更明显的错误。如果跨插件依赖是可选的,则应使用核心提供的 optionalRequire 辅助函数。

  3. 细微的时序变化 在极少数情况下可能引发问题。由于插件代码现在被编译为原生 ES 模块,模块作用域内的任何内容都会立即执行。如果您在模块作用域中有任何不寻常的逻辑,可能需要将其移至运行时代码中(例如,放在类构造函数内或类似位置)。

如果您遇到上述任何问题并需要帮助解决,请随时在下方发帖。

CORS / Access-Control-Allow-Origin 错误

如果在更新后遇到 CORS 错误,并且您使用了 CDN,那么请运行完整的 CLI 重新构建(./launcher rebuild app),以应用 NGINX 配置中的 此更改

如果您使用 S3(或兼容 S3 的)存储来托管资源,则需要配置您的 CDN,以便为所有资源添加 Access-Control-Allow-Origin: * 响应头。

新的编译器现在在 Discourse 的 latest 版本中默认启用

我认为我的插件存在一个问题,与此更改有关:

感谢您的报告!正在查看中 :eyes:

编辑:已修复

有兴趣的人请注意,我将在今天的 Ember Europe 聚会中介绍我们新的插件构建系统 - 2026-03-26T18:00:00Z。这是一个完全远程的活动——欢迎所有人参加!