Skip to content

facebook/metro 0.82.0 introduced breaking change that breaks react-native Unable to resolve module node:crypto #524

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

Closed
efstathiosntonas opened this issue Mar 7, 2025 · 7 comments

Comments

@efstathiosntonas
Copy link

efstathiosntonas commented Mar 7, 2025

Hi,

[email protected] has introduced this breaking change:

The result after running bundler:

Error: Unable to resolve module node:crypto from /Users/stathis/IdeaProjects/xxxx/node_modules/nanoid/index.js: node:crypto could not be found within the project or in these directories:
  node_modules
> 1 | import { webcrypto as crypto } from 'node:crypto'
    |                                      ^
  2 | import { urlAlphabet as scopedUrlAlphabet } from './url-alphabet/index.js'
  3 | export { urlAlphabet } from './url-alphabet/index.js'
  4 | const POOL_SIZE_MULTIPLIER = 128
    at ModuleResolver.resolveDependency (/Users/stathis/IdeaProjects/xxxxx/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:150:15)
    at DependencyGraph.resolveDependency (/Users/stathis/IdeaProjects/xxxxx/node_modules/metro/src/node-haste/DependencyGraph.js:239:43)
    at /Users/stathis/IdeaProjects/xxxxx/node_modules/metro/src/lib/transformHelpers.js:165:21
    at resolveDependencies (/Users/stathis/IdeaProjects/xxxxx/node_modules/metro/src/DeltaBundler/buildSubgraph.js:42:25)
    at visit (/Users/stathis/IdeaProjects/xxxxx/node_modules/metro/src/DeltaBundler/buildSubgraph.js:83:30)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.all (index 10)
    at async visit (/Users/stathis/IdeaProjects/xxxxx/node_modules/metro/src/DeltaBundler/buildSubgraph.js:92:5)
    at async Promise.all (index 29)
    at async visit (/Users/stathis/IdeaProjects/xxxxx/node_modules/metro/src/DeltaBundler/buildSubgraph.js:92:5)

solution for now is to add unstable_enablePackageExports: false in metro config.

metro.config.js

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

module.exports = (async () => {
  const defaultConfig = await getDefaultConfig(__dirname);
  const { assetExts, sourceExts } = defaultConfig.resolver;

  const isProduction = process.env.NODE_ENV === 'production';

  const getTransformOptions = async () => ({
    transform: {
      experimentalImportSupport: true,
      inlineRequires: true,
      nonInlinedRequires: [
        'React',
        'react',
        'react-compiler-runtime',
        'react/jsx-dev-runtime',
        'react/jsx-runtime',
        'react-native'
      ]
    }
  });

  const metroConfig = {
    transformer: {
      babelTransformerPath: require.resolve('react-native-svg-transformer/react-native'),
      getTransformOptions,
    },
    resolver: {
      assetExts: [...assetExts.filter((ext) => ext !== 'svg'), 'bin', 'lottie'],
      sourceExts: [...sourceExts, 'svg'],
      unstable_enablePackageExports: false, <<<<------ this must be set to false
    }
  };

  return mergeConfig(defaultConfig, metroConfig);
})();
@vonovak
Copy link

vonovak commented Mar 7, 2025

hi @efstathiosntonas this is not very actionable without having a reproducer. Could you create one?

Also, it's unlikely that this is an issue in nanoid. It's either an issue in metro or in your code.
I'd recommend opening an issue in the metro repo, but please provide a repro. Otherwise this is not actionable.

@efstathiosntonas
Copy link
Author

hi @vonovak, I’ve already mentioned the issue to metro maintainers, let’s see the outcome.

I understand that this originated from metro and not nanoid, just wanted to bring this to the attention of nanoid maintainers.

About reproducer, just create a bare rn project with resolution [email protected], and run react-native start while you have nanoid imported.

@ai
Copy link
Owner

ai commented Mar 7, 2025

Try the solution from #515

@robhogan
Copy link

robhogan commented Mar 7, 2025

Metro maintainer here - Metro will now resolve package.json#exports if possible, ignoring "main" fields.

nanoid's exports map is:

"exports": {
    ".": {
      "browser": "./index.browser.js",
      "default": "./index.js"
    },
    "./non-secure": "./non-secure/index.js",
    "./package.json": "./package.json"
  },

Based on the legacy package.json#react-native main field it looks like ./index.browser.js is the intended entry point for RN.

React Native configures Metro to assert the react-native condition, so the simplest solution is to add that to the exports map:

"exports": {
    ".": {
      "browser": "./index.browser.js",
+     "react-native": "./index.browser.js",
      "default": "./index.js"
    },
    "./non-secure": "./non-secure/index.js",
    "./package.json": "./package.json"
  },

@ai
Copy link
Owner

ai commented Mar 7, 2025

Thanks. Fixed 27ee2c4

It will take a while for me to release because I need also to release a fix for 3.x.

@ai ai closed this as completed Mar 7, 2025
@robhogan
Copy link

robhogan commented Mar 7, 2025

Amazing, thanks @ai!

@efstathiosntonas
Copy link
Author

Fixed on 5.1.3 (for reference).

Thank you guys for the fast response in this one! ❤

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants