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

fix(core): prevent stash listener conflicts #59635

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

arturovt
Copy link
Contributor

@arturovt arturovt commented Jan 20, 2025

The stash event listener is a global function that might be unsafely overridden if multiple microfrontend applications exist on the page.

In this commit, we create a map of APP_ID to stash event listener functions. This map prevents conflicts because multiple applications might be bootstrapped simultaneously on the client (one rendered on the server and one rendering only on the client).

I.e., the code that might be used is:

// Given that `app-root` is rendered on the server
bootstrapApplication(AppComponent, appConfig);

bootstrapApplication(BlogRootComponent, appBlogConfig);

Two bootstrapped applications would conflict and override each other's code.

@angular-robot angular-robot bot added the area: core Issues related to the framework runtime label Jan 20, 2025
@ngbot ngbot bot added this to the Backlog milestone Jan 20, 2025
@arturovt arturovt force-pushed the fix/core-stash-conflicts branch 5 times, most recently from 93414f0 to 20b19ab Compare January 20, 2025 19:36
Comment on lines 237 to 238
const stashEventListener = stashEventListeners.get(appId)!;
stashEventListener(native, eventName, listenerFn);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The non null assertion deviates from a prior safety net where an empty closure would be used, so the following seems safer and less of a change:

Suggested change
const stashEventListener = stashEventListeners.get(appId)!;
stashEventListener(native, eventName, listenerFn);
const stashEventListener = stashEventListeners.get(appId);
stashEventListener?.(native, eventName, listenerFn);

Copy link
Contributor Author

@arturovt arturovt Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to optional chaining.

@arturovt arturovt force-pushed the fix/core-stash-conflicts branch from 20b19ab to 7c91668 Compare January 20, 2025 19:44
The stash event listener is a global function that might be unsafely overridden if multiple microfrontend applications exist on the page.

In this commit, we create a map of `APP_ID` to stash event listener functions. This map prevents conflicts because multiple applications might be bootstrapped simultaneously on the client (one rendered on the server and one rendering only on the client).

I.e., the code that might be used is:

```ts
// Given that `app-root` is rendered on the server
bootstrapApplication(AppComponent, appConfig);

bootstrapApplication(BlogRootComponent, appBlogConfig);
```

Two bootstrapped applications would conflict and override each other's code.
@arturovt arturovt force-pushed the fix/core-stash-conflicts branch from 7c91668 to f29a5a8 Compare January 20, 2025 20:27
@arturovt arturovt marked this pull request as ready for review January 21, 2025 04:13
@pullapprove pullapprove bot requested a review from thePunderWoman January 21, 2025 04:13
Copy link
Contributor

@thePunderWoman thePunderWoman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll definitely need some tests here for this so we don't regress in the future. Can you add those?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: core Issues related to the framework runtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants