在主题组件中覆盖插件javascript

继续关于 将主题 Javascript 分成多个文件 的讨论:

之前有人讨论过在主题中开发还是在插件中开发。https://www.pfaffmanager.com/ 的 Rails 部分开始变得相当稳定,我想做的是将 Rails 部分的开发移到一个主题组件中。这进行得很顺利,主题组件中的模板和初始化程序的更改正如预期那样覆盖了插件。但是,主题中的 javascripts/discourse/components/server-item.js.es6 文件更改并没有覆盖插件中相同的文件。

我想我可能需要从插件中完全移除 Ember 的部分,让它只存在于主题中,但这听起来需要一天的工作量才能将所有这些部分移动、测试并推送到服务器。我是否遗漏了什么简单的东西?我应该忍痛将我想放在主题组件中的东西从插件中完全移除吗?我应该把所有东西都保留在插件中吗?

主题组件和插件中存在相同的代码,这让我觉得有点奇怪——我认为最好是在主题组件/插件之间做出选择,然后全力以赴。我们自己不会覆盖整个文件,我们也不推荐这样做。要覆盖核心/插件行为,您的主题组件应使用诸如 api.modifyClass 之类的方法。

我怀疑根本原因在于插件 ES6 模块的前缀与核心/主题模块的前缀不同。在您的网站上运行此代码,我看到模块的前缀是 plugin。我怀疑如果您启用了主题组件,我们会看到另一个条目,但带有不同的前缀。

Screenshot 2022-01-04 at 10.53.36

1 个赞

嗯,对我来说,整个Ember都显得有点奇怪。:man_shrugging:

好的。我将坚持使用包含所有JavaScript的单个插件。

而且那个Object.keys魔法非常酷,我以前从未想过。我非常感谢你。你说得对:

(4) ['discourse/plugins/Pfaffmanager/discourse/components/compact-server-item',
'discourse/plugins/Pfaffmanager/discourse/components/server-item',
'discourse/theme-11/components/server-item',
'discourse/theme-11/components/compact-server-item']
1 个赞

我总体上同意,但也有一些特殊情况:

  1. javascript 的更改量远远超过后端更改量,在这种情况下,主题组件是快速部署和测试部署代码的好方法。

  2. 大多数功能都可以通过基础主题组件交付,但添加一个补充插件可以增加仅靠 Javascript 无法实现的附加功能。我在主题列表预览中采用了这种技术,其中组件完成了插件所能实现功能的 90%,但如果您还添加了插件,您还可以获得一些额外的很酷的功能。

话虽如此,将所有内容打包到插件中有意义,因为在配置和安装方面混乱更少,而且所有内容始终保持同步。

3 个赞

但是,即使在您的插件+主题场景中,我也不会在插件和主题中重复 Ember 代码。因此,我需要至少将大部分模板、初始化程序、组件从插件中提取出来,并将它们只保留在主题组件中。

由于只有我一个人会对配置感到困惑,所以这也不是什么大问题。我真的很喜欢通过切换到主题的 beta 版本来在实时站点上测试一些新的前端东西的想法。

2 个赞

将服务器端内容放在插件中,将客户端内容放在主题中,这是非常有意义的——我们自己也是这么做的 :+1:

我的反对意见是同时在主题和插件中定义同一个 JavaScript 文件。

2 个赞

好的,这样大家都在同一页面上了 :+1:t2:

3 个赞

我很感谢你们能帮我解决这个问题。

我看到的另一个问题是运行 qunit 测试。 (我将假装我能弄清楚如何添加任何测试,这本身就是另一个问题;我认为我的问题是我不知道如何用数据来启动测试以显示内容……)。我认为如果我的插件中有 qunit 测试,那么当我推送到 github 时它们就会运行(因为我相当确定我曾见过我失败的测试)。

我能否获得一个主题组件来实现同样的目的?

1 个赞

技术上应该是可行的,但我认为我们还没有现成的 GitHub Actions 工作流来处理主题。主题测试目前正在进行一些调整(为了迁移到 ember-cli),但之后,也许我们能够将一些主题测试工作流模板添加到 GitHub - discourse/.github

2 个赞

模板也一样吗?

场景:我想覆盖插件中部署的模板。但我希望以代码可控的方式进行覆盖。

所以我尝试将新模板打包到主题组件中。同一个文件存在于插件中(但内容不同)。

这在我的开发云安装中似乎可行,但在标准的生产安装中却不行。

那么,是否可以说你无法预测模板覆盖是否会成功?也就是说,资产管道是不可预测的,你无法预测哪个“模板”会生效,因为没有预定义或可预测的优先级?

我一直有一个奇怪的假设,认为存在一个层级结构,类似于:

  • 核心
  • 插件
  • 主题组件
  • 本地站点更改

如果在该层级结构中较晚的级别放置一个具有相同路径和名称的“文件”,它将覆盖任何“先前”的定义。

但我的假设可能不安全?

那么,除了本地站点更改之外,唯一的“打包”解决方案是否就是分叉该插件并直接在其内部进行更改?

在某种程度上,这会很可惜,因为它会增加自定义的维护工作量,因为你需要定期将更改合并到主插件存储库中……

最好的方法是更新现有插件,并为其提供插件出口和/或自定义 API,主题组件可以使用该 API。

我上面的评论是专门关于覆盖整个 JS 文件(即 es6 模块)的。这是不可能的。资产管道会自动在插件/主题模块前加上插件/主题名称/ID,因此不可能与核心产生冲突。

对于模板,我们知道人们(包括我们在某些情况下)确实会覆盖它们,所以我们可能会让该系统继续运行。但请记住,这是一种 hack。如果原始组件/控制器更改了其行为,您覆盖的模板可能会导致站点中断。

总的来说,我认为您提到的层次结构(核心、插件、主题)应该是正确的——所以如果您看到不同的情况,请分享插件和主题中文件路径的详细信息。

3 个赞

谢谢您的确认。我的问题其实是无关的,澄清之后我找到了正确的地方!:blush:

2 个赞