-
Notifications
You must be signed in to change notification settings - Fork 31
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
getModalizer backward incompatibility issue #290
Comments
May you please clarify which Fluent version are you using? |
If I understand things correctly, you want to use two versions simultaneously with the core of one version and the parts from another version. That wouldn't and shouldn't work. From the public API perspective Tabster should be compatible between the major versions. So, you should add a resolution to 4.6.0 from the host side first. There should be just one copy of Tabster in the bundle. It doesn't concern just Tabster. If you need to use separate versions of anything simultaneously, you need to isolate the guests from the host using iframes. |
@lesyk we're in the way to upgrade Fluent UI from 9.18.2 to 9.22.0. since tabster is not locked by Fluent UI (range using |
@mshoho Thanks for your comments. I've also tested the case that host version 4.6.0 + guest version 4.2.0, it would also throw because of the I understand that this micro-frontend pattern is less popular, but I think such requirement would exist. Let me try to explain more. Our project is a WebUI embedded and shipped in Edge browser, so there's no way to populate 1 version immediately to all clients. We need to consider the time for users to check and download updates as well as release channels. I firstly would like to suggest we skip iframe solution because iframe has its own problems in user experience and development, and we cannot quickly switch to iframes now given that we've spent much effort on current architecture since the era with Fluent UI v8. Because both projects are developed, built and shipped separately, it is difficult to keep only 1 version of And because version propagation takes time, it's difficult to avoid the coexistence of different We've done several updates of Fluent UI and this is the first time we have this incompat issue. |
@KagamiChan it is not about the less popular pattern. If you have a library that provides, let's say, And nobody will guarantee the compatibility of the private internal APIs between the versions. They are internal and private. Things will get even worse between the major versions where nobody will guarantee even the public API compatibility. So, if the system uses A.v1 and B.v2 together at the same time, it's not a pattern issue, it is a system's design flaw. The fact that this is the first issue of that type you have encountered is likely just a sheer amount of luck. If you couldn't isolate things using iframes for some reason, your system should fundamentally address that flaw somehow differently. For example, you can try to avoid bundling the component library (and relative deps) inside both Host and Guest and use it as a separate dependency that is imported by Host and Guest at runtime from the same location. Or something else. The system shouldn't allow mixing parts of external deps from different versions in the same runtime. |
Would it be helpful if tabster instance is more self-contained? for example, instead of calling an utility function Thanks for you suggestion, but I'm afraid this often works well on web apps but not in our product's case. For us, host A and guest B are released separately and in parallel, and it depends on clients to check and download updates, adding up that there're multiple channels to release our projects to. This creates a dependency for B on A's version. Well I understand that tabster might have to be a singleton for its design purpose, and while I need to discuss more within our team on your suggested solution, I'm planning to do a quick mitigation to patch the old tabster instance from guest UI side: export const renderGuestUI = (root: HTMLElement) => {
const tabster = getTabster(window);
if (compare((tabster as any).core._version ?? '9.9.9', '4.3.0', '<')) {
(tabster as any).core.queueInit = (callback: () => void) => setTimeout(callback, 0);
(tabster as any).core.drainInitQueue = () => {};
(tabster as any).core._dummyObserver.updatePositions = () => {};
}
ReactDOM.render(<App />, root);
}; This does not intend to fix the missing functionality, and something might not work properly. All its purpose is to prevent crashing the UI before the new version of host reaches the client side. |
tabster.getModalizer means that it is not treeshakable and the modalizer code will get into the bundle regardless of being not used. A better way to mitigate would be to call But again, it seems to me that your system's design is asking for trouble and should be addressed from that point of view. |
Our product is micro-frontend alike architecture, there's a host UI project and several guest UI projects that are all built and shipped differently, and all the dependencies are not shared. We discovered an issue during the upgrade of FluentUI v9, which is caused by different versions of tabster in host UI side and guest UI side.
A minimal repro could be found here: https://github.com/KagamiChan/multiple-fluentui-repro
I'm not using codesandbox because I need to use yarn resolutions to lock tabster version, please let me know if you prefer a codesandbox example.
tabster versions:
Host UI: 4.2.0
Guest UI: 4.6.0
main difference for this issue: tabster 4.3.0 introduces queue for initialization: #262
Steps to repro:
what happened:
getModalizer
function andModalizerAPI
class is from guest UI (v4.6.0) so it calls tabster isntance'squeueInit
functionqueueInit
function, the exception throwsThis issue is blocking us from the Fluent UI upgrade because we have to upgrade host UI everywhere but that would be difficult (our product is not served on web but is embedded), could you please help take a look and help us unblock?
The text was updated successfully, but these errors were encountered: