-
-
Notifications
You must be signed in to change notification settings - Fork 301
feat(runtime): provide a root #3740
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
base: main
Are you sure you want to change the base?
Changes from 2 commits
8f19488
ce41110
ee1a2ac
46b008a
b1c2710
7d26e13
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React, { Suspense, lazy } from 'react'; | ||
import { createRoot } from 'react-dom/client'; | ||
import { loadRemote } from '@module-federation/enhanced/runtime'; | ||
|
||
class CustomElement extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: 'open' }); | ||
} | ||
async connectedCallback() { | ||
if (!this.shadowRoot) return; | ||
|
||
const module = await loadRemote('dynamic-remote/ButtonOldAnt', { | ||
//@ts-ignore | ||
root: this.shadowRoot, | ||
}); | ||
//@ts-ignore | ||
createRoot(this.shadowRoot).render(React.createElement(module.default)); | ||
} | ||
} | ||
|
||
customElements.define('custom-element', CustomElement); | ||
|
||
function DynamicRemoteButton() { | ||
return React.createElement('custom-element'); | ||
} | ||
|
||
export default DynamicRemoteButton; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,6 +70,7 @@ export function preloadAssets( | |
assets: PreloadAssets, | ||
// It is used to distinguish preload from load remote parallel loading | ||
useLinkPreload = true, | ||
root: HTMLElement = document.head, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A fatal flaw with the current approach is that when you load something (or preload something) it gets cached by id in a global. Subsequent calls to retrieve assets no longer returns those assets. So ultimately, Federation only supports a single root per global. 😞 To fix this I think we'd need to make sure that this code: Somehow respects caches on whether it's been loaded for a specific root. Not assuming a global loading approach. |
||
): void { | ||
const { cssAssets, jsAssetsWithoutEntry, entryAssets } = assets; | ||
|
||
|
@@ -99,6 +100,7 @@ export function preloadAssets( | |
}; | ||
cssAssets.forEach((cssUrl) => { | ||
const { link: cssEl, needAttach } = createLink({ | ||
root, | ||
url: cssUrl, | ||
cb: () => { | ||
// noop | ||
|
@@ -116,7 +118,7 @@ export function preloadAssets( | |
}, | ||
}); | ||
|
||
needAttach && document.head.appendChild(cssEl); | ||
needAttach && root.appendChild(cssEl); | ||
}); | ||
} else { | ||
const defaultAttrs = { | ||
|
@@ -125,6 +127,7 @@ export function preloadAssets( | |
}; | ||
cssAssets.forEach((cssUrl) => { | ||
const { link: cssEl, needAttach } = createLink({ | ||
root, | ||
url: cssUrl, | ||
cb: () => { | ||
// noop | ||
|
@@ -143,7 +146,7 @@ export function preloadAssets( | |
needDeleteLink: false, | ||
}); | ||
|
||
needAttach && document.head.appendChild(cssEl); | ||
needAttach && root.appendChild(cssEl); | ||
}); | ||
} | ||
|
||
|
@@ -154,6 +157,7 @@ export function preloadAssets( | |
}; | ||
jsAssetsWithoutEntry.forEach((jsUrl) => { | ||
const { link: linkEl, needAttach } = createLink({ | ||
root: document.head, | ||
url: jsUrl, | ||
cb: () => { | ||
// noop | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Behavior is odd... Loading the page directly attaches the CSS correctly, navigating to it through a link doesn't because css assets is missing in the manifest... It's almost like the built code caches something different than the hardened runtime which uses mf-manifest.json?