Skip to content

feat: Expose MetroConfig type directly from @react-native/metro-config#46602

Closed
tjzel wants to merge 1 commit into
facebook:mainfrom
tjzel:@tjzel/metro-config/export-MetroConfig-type-directly
Closed

feat: Expose MetroConfig type directly from @react-native/metro-config#46602
tjzel wants to merge 1 commit into
facebook:mainfrom
tjzel:@tjzel/metro-config/export-MetroConfig-type-directly

Conversation

@tjzel
Copy link
Copy Markdown
Contributor

@tjzel tjzel commented Sep 23, 2024

Summary:

React Native app template provided by the CLI currently uses metro-config directly for MetroConfig type.
However, it doesn't have metro-config as neither a dependency or dev dependency, which can lead to version mismatches.

While this is obviously a mistake on the template repo side, metro-config versions aren't matched with react-native versions. Therefore, getting the correct version of metro-config from @react-native/metro-config would require reflecting on @react-native/metro-config's package.json etc. which is far from ideal. In my opinion it's would be much better to expose MetroConfig type from @react-native/metro-config directly.

Version mismatching can happen in a monorepo setup. Say we have the monorepo structure using Yarn Modern:

.
├── RN75-app (workspace)
├── RN76-app (workspace)
│   ├── metro.config.js
│   └── node_modules
│       └── @react-native
│           └── metro-config (0.76)
│               └── node_modules
│                   └── metro-config (version for 0.76)
└── node_modules
    ├── @react-native 
    │   └── metro-config (0.75)
    └── metro-config (version for 0.75)

react-native@0.75 gets hoisted to the monorepo root while react-native@0.76 sits in an RN 0.76 app workspace.

Say we have the following RN76-app/metro.config.js contents:

const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

/**
 * Metro configuration
 * https://reactnative.dev/docs/metro
 *
 * @type {import('metro-config').MetroConfig}
 */
const config = {};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

In this case, require('@react-native/metro-config') would resolve to RN76-app/node_modules/@react-native/node_modules/metro-config since @react-native/metro-config is a (dev) dependency of the App.

However import('metro-config).MetroConfig would resolve to node_modules/metro-config since it's not a direct dependency.

This is how we have a mismatch - imported functions come from different packages than imported type.

Changelog:

[GENERAL] [ADDED] - Expose MetroConfig type directly from @react-native/metro-config.

Test Plan:

yarn build to generate dist for @react-native/metro-config, see it has the export of MetroConfig.

Notes

If this PR gets approved, I'll submit relevant one to the CLI template.

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Software Mansion Partner: Software Mansion Partner Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels Sep 23, 2024
Copy link
Copy Markdown
Contributor

@robhogan robhogan left a comment

Choose a reason for hiding this comment

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

LGTM, thanks @tjzel

@facebook-github-bot
Copy link
Copy Markdown
Contributor

@robhogan has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Copy Markdown
Contributor

@robhogan merged this pull request in cc6d1eb.

@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Oct 7, 2024
@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @tjzel in cc6d1eb

When will my fix make it into a release? | How to file a pick request?

blakef pushed a commit that referenced this pull request Oct 7, 2024
#46602)

Summary:
React Native [app template provided by the CLI](https://github.com/react-native-community/template) currently uses [`metro-config` directly for `MetroConfig` type](https://github.com/react-native-community/template/blob/main/template/metro.config.js#L7).
However, it doesn't have `metro-config` as neither a dependency or dev dependency, which can lead to version mismatches.

While this is obviously a mistake on the template repo side, `metro-config` versions aren't matched with `react-native` versions. Therefore, getting the correct version of `metro-config` from `react-native/metro-config` would require reflecting on `react-native/metro-config`'s package.json etc. which is far from ideal. In my opinion it's would be much better to expose `MetroConfig` type from `react-native/metro-config` directly.

Version mismatching can happen in a monorepo setup. Say we have the monorepo structure using Yarn Modern:

```tree
.
├── RN75-app (workspace)
├── RN76-app (workspace)
│   ├── metro.config.js
│   └── node_modules
│       └── react-native
│           └── metro-config (0.76)
│               └── node_modules
│                   └── metro-config (version for 0.76)
└── node_modules
    ├── react-native
    │   └── metro-config (0.75)
    └── metro-config (version for 0.75)
```

`react-native@0.75` gets hoisted to the monorepo root while `react-native@0.76` sits in an RN 0.76 app workspace.

Say we have the following `RN76-app/metro.config.js` contents:

```js
const {getDefaultConfig, mergeConfig} = require('react-native/metro-config');

/**
 * Metro configuration
 * https://reactnative.dev/docs/metro
 *
 * type {import('metro-config').MetroConfig}
 */
const config = {};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
```

In this case, `require('react-native/metro-config')` would resolve to `RN76-app/node_modules/react-native/node_modules/metro-config` since `react-native/metro-config` is a (dev) dependency of the App.

However `import('metro-config).MetroConfig` would resolve to `node_modules/metro-config` since it's not a direct dependency.

This is how we have a mismatch - imported functions come from different packages than imported type.

## Changelog:

[GENERAL] [ADDED] - Expose `MetroConfig` type directly from `react-native/metro-config`.

Pull Request resolved: #46602

Test Plan:
`yarn build` to generate dist for `react-native/metro-config`, see it has the export of `MetroConfig`.

## Notes

If this PR gets approved, I'll submit relevant one to the CLI template.

Reviewed By: huntie

Differential Revision: D63258881

Pulled By: robhogan

fbshipit-source-id: e6f3c880eb4a0aa902c62932d58f243c38b07c2e
@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @tjzel in 273ad9c

When will my fix make it into a release? | How to file a pick request?

@blakef blakef mentioned this pull request Oct 30, 2024
github-merge-queue Bot pushed a commit to software-mansion/react-native-reanimated that referenced this pull request Nov 18, 2024
## Summary

Since

- facebook/react-native#46602

got merged we can apply the fixes. Helps on CI.

## Test plan
🚀
r0h0gg6 pushed a commit to r0h0gg6/react-native-reanimated that referenced this pull request Jul 28, 2025
## Summary

Since

- facebook/react-native#46602

got merged we can apply the fixes. Helps on CI.

## Test plan
🚀
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. Merged This PR has been merged. p: Software Mansion Partner: Software Mansion Partner 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.

4 participants