【问题标题】:How to handle Svelte custom-element cross-dependencies and `Failed to execute 'define' on 'CustomElementRegistry`如何处理 Svelte 自定义元素交叉依赖项和“无法在“CustomElementRegistry”上执行“定义”
【发布时间】:2020-08-31 21:55:03
【问题描述】:

上下文:我们正在构建一个 Svelte UI 组件库作为自定义元素,以便在多个新旧应用程序中使用。所有组件都以包的形式存在于 monorepo 中,并且可以自行维护和交付。

目标:提供小型通用 js 包,可以以最少的开销由消费者临时使用。

情况:

  • 存在一个简单的(原子)自定义元素,例如 our-button
  • 存在另一个更复杂的自定义元素our-modal,它使用(导入)our-button

如果消费者将our-button-bundle.js 带入一个地方使用并且 our-modal-bundle.js 重复our-button 导致:

Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "our-button" has already been used with this registry

更不用说,这是为按钮引入了两次代码,这很臃肿。

为什么不使用构建工具...?理想情况下,我们希望消费者在这里几乎不费吹灰之力。支持的应用程序包括 WebForms、ASP .NET 等。作为一个 ui 团队,我们只希望他们指向一些 js 捆绑包,然后开展他们的业务。我们维护和推动,他们导入和实施。 (嘿,一个团队至少可以做梦……)

到目前为止可能的选择:

  • all.bundle.js 没有重复代码或命名,但 臃肿。抱歉,最终用户,您得到了整个库,无论应用程序使用一个还是多个。
  • 一个core.bundle.js 或常见的小型可重复使用的元素(类似于供应商),以及另一个较大的分子状组件。我看不出这是如何工作的。使用自定义元素 - 预编译的模态如何在没有按钮的情况下编译?如何在开发模式下工作?
  • 围绕自定义元素定义的运行时脚本,例如:
if (!window[MY_ELEMENT_NAME]) {
 // register...
} else {
 return;
}

同样,此选项将通过网络发送重复的代码,但只应注册和使用元素的一个实例。

我们也不能在我们的组件之间导入任何共享模块,但我觉得这违背了组件的全部目的。

欢迎针对这种情况提出任何有关架构的建议。

【问题讨论】:

  • 我应该注意到其中一个 monorepo 包是我们用于 UI 库文档的 Sapper 站点。在这种情况下,我们将组件作为原生 Svelte 引入。简单得多,但是客户端 api 交付选项对于我们希望我们的应用程序开发人员必须处理的开销来说有点沉重。

标签: architecture web-component svelte custom-element uicomponents


【解决方案1】:

简短的回答是您需要将组件作为单独的模块分发,这样当有人导入 our-button 并随后导入 our-modal 时,our-modal 使用模块注册表中已经存在的 our-button 的副本。

这确实意味着每个(顶级)元素都需要自己的导入,并且与分发粗粒度包相比,浏览器必须下载更多模块,但消费者可以选择创建自己的包.

Shimport — 免责声明:我写的 — 允许您在极少数不支持它们的浏览器中使用本机模块。)

【讨论】:

  • 谢谢里奇。我们将测试这种方法的某种形式,然后用我们整理出来的任何东西重新回到这里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 2020-06-17
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 2020-01-30
相关资源
最近更新 更多