Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support scoped custom element registries #44110

Open
jpzwarte opened this issue Nov 8, 2021 · 0 comments
Open

Support scoped custom element registries #44110

jpzwarte opened this issue Nov 8, 2021 · 0 comments

Comments

Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant
@jpzwarte
Copy link

@jpzwarte jpzwarte commented Nov 8, 2021

Which @angular/* package(s) are relevant/releated to the feature request?

compiler, core, elements

Description

When using microfrontends, you can have the following setup:

  • app-shell
  • microfrontend A (implemented using lit.dev + web component design system)
  • microfrontend B (implemented using angular elements + web component design system)

So the app shell dynamically loads a microfrontend javascript bundle and instantiates the web component and appends it to the DOM in the correct location.

Microfrontend B is implemented using angular elements so the entire angular app is wrapped in a custom element and it won't conflict with any other microfrontends built using Angular (possibly with a different angular version)

Now the problem arises when A & B use different versions of the design system npm package. Say you have <x-button> versions 1 and 2 in the design system. The first one who registers the custom element via window.customElements.define('x-button', Button) "wins". The second one who attempts that gets an exception.

Even if you detect if x-button is already defined, you still have issues because A & B expect a specific version of the custom element.

Proposed solution

There is a proposal to handle this, written by @justinfagnani https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Scoped-Custom-Element-Registries.md

This basically comes down to custom elements having a "local" CustomElementRegistry and children of that customElement using that local version instead of the global window.customElements one.

I would propose @angular/elements having an option to use the above proposal. And then having any web component children not using document.createElement, but somehow using a local CustomElementRegistry to instantiate the elements.

In plain web components, every shadowRoot basically "inherits" the local CustomElementRegistry. In Angular however you can have a mix of angular & web components. So not every web components has a parent web component. So you would probably have some sort of CustomElementRegistry injectable that Ivy/Renderer3 then uses to create the element instead of document.createElement.

Alternatives considered

The only workaround I see so far is to use an <iframe> to host the angular microfrontend. That way all web components are isolated to the iframe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment