Skip to content

Conversation

jbroma
Copy link
Contributor

@jbroma jbroma commented Jun 4, 2025

Summary

Part of #1480

This PR adds __METRO_GLOBAL_PREFIX__ to other require polyfill methods. With Module Federation we use multiple module system in runtime which creates a need for separating module systems from each other with globalPrefix.

Changelog: [Feature] Add global prefix to other module functions in require polyfill

Test plan

TBD

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 4, 2025
robhogan

This comment was marked as spam.

robhogan

This comment was marked as spam.

@jbroma
Copy link
Contributor Author

jbroma commented Jun 5, 2025

Fix test to use __customPrefix__r

on the other hand, we discussed that it might not be needed to add the prefix to __r but after closer inspection it turns out it's necessary - I'm wondering whether we should introduce a separate prefix for __r or keep it as it is in this PR (prefixed with __METRO_GLOBAL_PREFIX__)?

@jbroma jbroma marked this pull request as ready for review June 27, 2025 17:58
@jbroma
Copy link
Contributor Author

jbroma commented Jun 27, 2025

Fix test to use __customPrefix__r

on the other hand, we discussed that it might not be needed to add the prefix to __r but after closer inspection it turns out it's necessary - I'm wondering whether we should introduce a separate prefix for __r or keep it as it is in this PR (prefixed with __METRO_GLOBAL_PREFIX__)?

cc @robhogan do you think we should create a separate prefix for __r?

We've added tests to the PR and marked it as ready to review, let me know if there is anything left to be done here to proceed with this PR 🙏

@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Jun 27, 2025
@robhogan
Copy link
Contributor

robhogan commented Jul 2, 2025

We'll need to update this as well so users with a custom global prefix but default getRunModuleStatement don't get broken:

getRunModuleStatement: (moduleId: number | string) =>
`__r(${JSON.stringify(moduleId)});`,

@robhogan
Copy link
Contributor

robhogan commented Jul 2, 2025

LGTM in principle, importing to run internal tests

@facebook-github-bot
Copy link
Contributor

@robhogan has imported this pull request. If you are a Meta employee, you can view this in D77659025.

@jbroma
Copy link
Contributor Author

jbroma commented Jul 2, 2025

We'll need to update this as well so users with a custom global prefix but default getRunModuleStatement don't get broken:

getRunModuleStatement: (moduleId: number | string) =>
`__r(${JSON.stringify(moduleId)});`,

there is 2 ways to achieve this:

  • we can modify the returned statement to do some runtime interpolation and include the __METRO_GLOBAL_PREFIX__ from current scope
  • we can augument the getRunModuleStatement with another param that will insert the prefix at build time

what would you suggest here?

@jbroma
Copy link
Contributor Author

jbroma commented Jul 29, 2025

@robhogan any suggestions on how to move forward with this PR?

facebook-github-bot pushed a commit that referenced this pull request Sep 2, 2025
…Statement`

Summary:
To allow prefixing the global function `__r` (e.g., #1512), expose the prefix to the configured [`getRunModuleStatement`](https://metrobundler.dev/docs/configuration/#getrunmodulestatement), which returns the `__r()` call as a string.

```
 - **[Feature]** Expose `globalPrefix` to `getRunModuleStatement`
```

## Alternative? Runtime prefixing
We could alternatively add prefix at runtime by emitting:
```
'globalThis[__METRO_GLOBAL_PREFIX__ + '__r'](/*...*/)'
```
There are a couple of downsides -
 - These runModule statements are currently outside IIFEs that inject `global` based on (something like) `global = globalThis ?? global ?? window` - we don't rely on the existence of `globalThis` elsewhere (though it's probably safe to now - that's a separate breaking change).
 - Concatenation/interpolation + object access is more verbose and slightly slower, and there's just no need for it in code emitted by Metro itself (as opposed to framework/userland code, which must use it).

Differential Revision: D81476621
@robhogan
Copy link
Contributor

robhogan commented Sep 2, 2025

Ideally I think we add the prefix at build time - should be possible to add on top of #1566

facebook-github-bot pushed a commit that referenced this pull request Sep 2, 2025
…Statement` (#1566)

Summary:
Pull Request resolved: #1566

To allow prefixing the global function `__r` (e.g., #1512), expose the prefix to the configured [`getRunModuleStatement`](https://metrobundler.dev/docs/configuration/#getrunmodulestatement), which returns the `__r()` call as a string.

```
 - **[Feature]** Expose `globalPrefix` to `getRunModuleStatement`
```

## Alternative? Runtime prefixing
We could alternatively add prefix at runtime by emitting:
```
"globalThis[__METRO_GLOBAL_PREFIX__ + '__r'](/*...*/)"
```
There are a couple of downsides -
 - These runModule statements are currently outside IIFEs that inject `global` based on (something like) `global = globalThis ?? global ?? window` - we don't rely on the existence of `globalThis` elsewhere (though it's probably safe to now - that's a separate breaking change).
 - Concatenation/interpolation + object access is more verbose and slightly slower, and there's just no need for it in code emitted by Metro itself (as opposed to framework/userland code, which must use it).

Reviewed By: huntie

Differential Revision: D81476621

fbshipit-source-id: 90641cf21491711c56606131ec4c5797b7b00020
@facebook-github-bot
Copy link
Contributor

@robhogan has imported this pull request. If you are a Meta employee, you can view this in D77659025.

1 similar comment
@facebook-github-bot
Copy link
Contributor

@robhogan has imported this pull request. If you are a Meta employee, you can view this in D77659025.

@robhogan robhogan added this to the Next breaking release milestone Sep 4, 2025
@jbroma
Copy link
Contributor Author

jbroma commented Sep 8, 2025

I believe that because of changes in #1566 we should also change the default to include the __METRO_GLOBAL_PREFIX__, in a separate PR though

@robhogan
Copy link
Contributor

robhogan commented Sep 9, 2025

Yes, but tbh I think these need to be the same PR or at least merged simultaneously - users may have already configured globalPrefix, but if so with the default getRunModuleStatement they'd be broken by this PR. The two together is non-breaking for a given config that customises globalPrefix. (Unavoidably breaking for users customising getRunModuleStatement)

(Related, but separately, does anyone need to customise getRunModuleStatement? I wouldn't remove it immediately but I'm inclined to deprecate it)

CC @tjzel - IIRC worklets rely on the details here.

@jbroma
Copy link
Contributor Author

jbroma commented Sep 10, 2025

Yes, but tbh I think these need to be the same PR or at least merged simultaneously - users may have already configured globalPrefix, but if so with the default getRunModuleStatement they'd be broken by this PR. The two together is non-breaking for a given config that customises globalPrefix. (Unavoidably breaking for users customising getRunModuleStatement)

yeah, let's aim to merge those 2 one after another 👍

@tjzel
Copy link

tjzel commented Sep 10, 2025

Thanks for the ping.

We don't use getRunModuleStatement in Worklets now. We probably could to make some code less hacky but that would be only a minor improvement.

Just to make sure, after these changes, to obtain the __r function from JSI in C++ we have to make the following amendment?

- auto require = rt.global().getPropertyAsFunction(rt, "__r");
+ auto metroGlobalPrefix = rt.global().getProperty(rt, "__METRO_GLOBAL_PREFIX__");
+ auto requireName = metroGlobalPrefix + "__r";
+ auto require = rt.global().getPropertyAsFunction(rt, requireName);

@jbroma
Copy link
Contributor Author

jbroma commented Sep 10, 2025

Just to make sure, after these changes, to obtain the __r function from JSI in C++ we have to make the following amendment?

- auto require = rt.global().getPropertyAsFunction(rt, "__r");
+ auto metroGlobalPrefix = rt.global().getProperty(rt, "__METRO_GLOBAL_PREFIX__");
+ auto requireName = metroGlobalPrefix + "__r";
+ auto require = rt.global().getPropertyAsFunction(rt, requireName);

Correct 👍

I had a quick look but it seems to be one of the only uses of that in OSS 😅
Very nice this was spotted so soon!

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants