如何处理 Svelte 自定义元素交叉依赖性和“无法在“CustomElementRegistry"上执行“定义" [英] How to handle Svelte custom-element cross-dependencies and `Failed to execute 'define' on 'CustomElementRegistry`

查看:29
本文介绍了如何处理 Svelte 自定义元素交叉依赖性和“无法在“CustomElementRegistry"上执行“定义"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Context: We are building a library of Svelte UI components as Custom-Elements to be consumed across multiple newish and legacy applications. All components exist as packages in a monorepo, and can be maintained and delivered on their own.

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

Goal: to deliver small universal js packages that can be consumed ad-hoc with the least overhead by consumers.

情况:

  • 存在一个简单的(原子的)自定义元素,例如 our-button.
  • 存在另一个更复杂的自定义元素 our-modal,它使用(导入)our-button
  • a simple (atomic) custom-element such as our-button exists.
  • another more complex custom-element our-modal exists which utilizes (imports) our-button

如果消费者带来了 our-button-bundle.js 以在一个地方使用 our-modal-bundle.jsour-button 的重复导致:

If a consumer brings in our-button-bundle.js to be used in one place and our-modal-bundle.js the duplication of our-button causes:

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

更不用说,这是两次引入按钮的代码,这是膨胀的.

Not to mention, this is bringing in the code for button twice, which is bloat.

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

Why not use a build tool...? Ideally, we want the consumers to hardly lift a finger here. Supported apps include things like WebForms, ASP .NET, an others. As a ui team, we just want them to point as some js bundles, and go about their business. We maintain and push, they import and implement. (Hey, a team can dream at least...)

目前可能的选项:

  • 一个 all.bundle.js 没有重复的代码或命名,但是臃肿.抱歉,最终用户,无论应用使用一个还是多个,您都可以获得整个库.
  • 一个 core.bundle.js 或常见的小型可重用元素(类似于 Vendor),以及另一个类似组件的较大分子.我看不出这将如何运作.使用自定义元素 - 如何在没有按钮的情况下进行预编译模态编译?如何在开发模式下工作?
  • 围绕自定义元素定义的运行时脚本,例如:
  • An all.bundle.js No duplication of code, or naming, but Bloated. Sorry end user, you get the whole library, whether the app uses one piece, or many.
  • A core.bundle.js or common small re-usable elements (similar to Vendor), and another of larger molecule like components. I can't see how this would work. With custom elements - how can pre-compiled modal compile without button? How can it be worked on in dev mode?
  • A run-time script around the custom-element definitions like:
if (!window[MY_ELEMENT_NAME]) {
 // register...
} else {
 return;
}

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

Again, this option will send duplications of code over the wire, though only one instance of the element should be registered and used.

我们也永远不能跨组件导入任何共享模块,但我觉得这违背了组件的全部目的.

We could also never import any shared modules across our components, but I feel like this defeats the whole purpose of components.

欢迎对这种情况的架构提出任何建议.

Any suggestions on an architecture for this situation are welcomed.

推荐答案

简而言之,您需要将组件作为单独的模块进行分发,这样当有人导入 our-button 之后再导入our-modal, our-modal 使用模块注册表中已经存在的 our-button 副本.

The short answer is that you need to distribute the components as individual modules, such that when someone imports our-button and later imports our-modal, our-modal uses the copy of our-button that's already in the module registry.

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

This does mean that each (top-level) element needs its own import, and that the browser will have to download more modules than if you were distributing coarser-grained bundles, but consumers would have the option to create their own bundles.

(Shimport — 免责声明:我写的 — 允许您甚至在极少数浏览器不支持它们.)

(Shimport — disclaimer: I wrote it — allows you to use native modules even in the very few browsers that don't support them.)

这篇关于如何处理 Svelte 自定义元素交叉依赖性和“无法在“CustomElementRegistry"上执行“定义"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆