Skip to content

Support ESM react-native.config files #2167

Closed
@kraenhansen

Description

@kraenhansen

Describe the Feature

I'd love to use modern ESM code in my React Native apps and libraries. The CLI's config package currently blocks having "type": "module" in a React Native app or library package, because the config command loads config files synchronous, with a ~ 5 year old version of cosmiconfig.

Setting "type": "module" in a package.json of an app or dependency yields the following error:

error Failed to load configuration of your project.
Error [ERR_REQUIRE_ESM]: require() of ES Module {...}/rnc-cli-bug/react-native.config.js from {...}/node_modules/cosmiconfig/node_modules/import-fresh/index.js not supported.
react-native.config.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead rename react-native.config.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in {...}/rnc-cli-bug/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

Users cannot rename react-native.config.js to react-native.config.cjs because it's not in the list of files being searched for, even when patching that list, yields this error:

Error: No loader specified for extension ".cjs", so searchPlaces item "react-native.config.cjs" is invalid

So, there doesn't seem to exist any workaround for this.

Possible Implementations

I believe the best solution is to upgrade cosmicconfig to a more recent version and use their async API to load the config file.
This entails that the following methods would become async:

Which would in practice break the API of both the @react-native-community/cli and @react-native-community/cli-config packages and probably require a major version bump.

A less intrusive alternative, would be to upgrade but only support CommonJS configs and simply add react-native.config.cjs and fix the issue loading it.

Note: Upgrading cosmicconfig would have the added benefit of packages being able to declare their React Native configs in their package.json files too. But that should either be disabled or named differently to avoid conflicts with the react-native main field already relied upon by Metro.

I'd be willing to contribute a PR to fix this, if there's a good chance it'll be considered for review.

Related Issues

I'm surprised, but I can't seem to find existing issues mentioning this limitation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions