metro
metro copied to clipboard
Feature: support new package.json exports field
exports
field is a new standard which adoption will inevitably grow further as the ecosystem switches to full ESM as NodeJS 10 reaches EOL. It's probably best to support it before things break. Features:
- Export submodules with sub-path exports;
- Specific exports for both CJS and ESM modules.
Example of subpath exports from NodeJS docs:
{
"type": "module",
"name": "es-module-package",
"main": "./main.js",
"exports": {
".": "./main.js",
"./submodule": "./src/submodule.js"
}
}
The consumer of the library can now use:
import submodule from 'es-module-package/submodule';
// Loads ./node_modules/es-module-package/src/submodule.js
Is there any plan to support this any time soon?
Any workarounds?
Here's a workaround I used. In https://github.com/tinyplex/tinybase, I omit the "main"
field in my package.json
to prefer "exports"
.
To get this to work with Metro, I added a "react-native"
field that points to the file. It's apparently not documented, but this is used as a higher-priority location than "main"
. "browser"
is another option you might prefer.
Works a charm in https://github.com/tinyplex/tinybase/issues/17:

@robhogan any plans to support this? or we can enable it if it's behind some flag?
Without this feature it basically makes impossible to use most of ESM modules out there with react-native.
Hi all π, happy to share that exports
field support is on our roadmap for the second half of 2022. We haven't scheduled this work immediately, but once we have progress I will make sure to post an update here.
That's good news. @huntie hopefully this can get bumped up in priority. Lots of popular packages are beginning to drop commonjs support. Without full ESM support in metro react-native users are stuck on increasingly old/broken/insecure versions of packages.
Hey Folks π Since we are in the seccond half of 2022 already do we have an estimation when this feature will arrive or is there any workaround already ?
Update:
- We've been working on the design for this feature β now shared at https://github.com/react-native-community/discussions-and-proposals/pull/534. The details tacked in this proposal are essential for us to align on building the right thing and making implementation as swift and correct as possible.
- Implementation hasn't yet begun βΒ this may kick off in the next month.
Workarounds for apps remain possible by configuring resolver.resolveRequest
(configuring as documented). This will allow you to set overrides for specific import paths, to patch "exports"
functionality on a case-by-case basis.
Wow thats great, thanks for your answer π I'm glad to have a workaround. I will try it immediately π€
We ran into this issue while using fp-ts-std. Our current workaround within a monorepo setup is this:
// packages/app/metro.config.js
const path = require('path')
const { createMetroConfiguration } = require('expo-yarn-workspaces')
module.exports = (() => {
const workspaceRoot = path.resolve(__dirname, '../..')
const config = createMetroConfiguration(__dirname)
const { resolver } = config
config.resolver = {
...resolver,
extraNodeModules: new Proxy(resolver.extraNodeModules, {
get: (target, name) => (name === 'fp-ts-std' ? path.resolve(workspaceRoot, `node_modules/${name}/dist/esm`) : undefined)
})
}
return config
})()
Also missing is subpath imports, which was added in Node v14.6.0, v12.19.0.
All bundlers will always be behind nodejs itself. Makes me wonder why nodejs can't bundle JS itself.
Any updates? This is painful for JS library authors.
Yes I can give an update! π The implementation is well underway βΒ the most recent batch of commits starts with 38b96f872a92d0f0650c9af0250c8dc5599a6e62.
We're planning to ship Package Exports in the next Metro release, and βΒ fingers crossed β in time for React Native 0.72. For this launch, the feature will be disabled by default and marked "unstable", enabled by the resolver option unstable_enablePackageExports
.
Furthermore, this will be accompanied by a blog post on the React Native blog. I'll be writing up an explanation of the feature, plus instructions and gotchas for app developers and package maintainers who want to enable the feature today.
After this, we're aiming to stabilise Package Exports for React Native 0.73 (pending other priorities).
Great news, it is in beta now! π
https://reactnative.dev/blog/2023/06/21/0.72-metro-package-exports-symlinks#new-metro-features