Skip to content

Metro Troubleshooting Guide

Alexander Sklar edited this page Jun 12, 2020 · 6 revisions
  1. Common errors and solutions
  2. Metro internals
  3. Debugging Metro errors

Important

This page is linked to from http://aka.ms/RNWTroubleshootMetro. If you rename this page you need to update the link. The aka.ms link will show up in the RedBox UX.

Common errors and solutions

  1. SHA-1 for file filename (resolvedPath) is not computed
    • RNW devs: Make sure you've run yarn and yarn build if you've recently pulled the branch.
    • If you have a react-native.config.js in your app's directory, make sure your project's react-native.config.js points to the right reactNativeDirectory. You might get this file if you used your RNW repo to create the app by doing node C:\rnw\packages\react-native-windows-init\bin.js ... --version C:\rnw\vnext).

Metro internals

For more details on Metro, see https://github.com/microsoft/react-native-windows/wiki/Metro-Guide

Haste module collisions

Haste collisions typically occur when you have accidentally installed two different versions of the same package. When this happens, you'll see an error with "Haste module naming collision:". To troubleshoot this, you'll need to find out where the module is being imported from.
Tips

  1. The "yarn why fooBarPackage" command can be super useful for debugging this - it shows you where in the dependency graph a given package is being brought in from, and you can use this to determine why it's being used more than once.
  2. In metro.config.js there is a "blacklistRE" property which tells metro to exclude a given pattern. See https://facebook.github.io/metro/docs/configuration/ for more info. You can use this property to purposely exclude a directory if necessary. See https://stackoverflow.com/questions/41813211/how-to-make-react-native-packager-ignore-certain-directories for an example.

Watch out for case sensitivity

Metro makes an assumption that file paths stored in its internal file mapping (aka the haste map) are case sensitive. Because of this you need to take great care any place you specify paths in your metro.config.js (applies to watch, extraNodeModules, and possibly others) or react-native.config.js (applies to reactNativePath).

Tips

  1. Avoid hard-coding paths. Use path.resolve or require.resolve to find the path to directories.
  2. If you must hard-code a path, use the same case for file paths as you would see in a dir listing from cmd prompt.
  3. Be consistent with the case of paths in every place you specify a path in your config.
  4. Avoid hard-coding drive letters. If you must hard-code a drive letter, prefer upper-case.

Corrupted node_modules installation

You may get your node_modules into a corrupted state. I'm honestly not sure how this can happen. But the symptom looks like this exception being thrown as a bundle is being fetched from a successfully launched metro server:

(0 , _helperModuleTransforms.getModuleName) is not a function
    at PluginPass.exit (D:\rnw\node_modules@babel\plugin-transform-modules-commonjs\lib\index.js:140:70)
    at newFn (D:\rnw\node_modules@babel\traverse\lib\visitors.js:179:21)
    at NodePath._call (D:\rnw\node_modules@babel\traverse\lib\path\context.js:55:20)
    at NodePath.call (D:\rnw\node_modules@babel\traverse\lib\path\context.js:42:17)
    at NodePath.visit (D:\rnw\node_modules@babel\traverse\lib\path\context.js:99:8)
    at TraversalContext.visitQueue (D:\rnw\node_modules@babel\traverse\lib\context.js:112:16)
    at TraversalContext.visitSingle (D:\rnw\node_modules@babel\traverse\lib\context.js:84:19)
    at TraversalContext.visit (D:\rnw\node_modules@babel\traverse\lib\context.js:140:19)
    at Function.traverse.node (D:\rnw\node_modules@babel\traverse\lib\index.js:84:17)

Tips
The workaround is to delete your node_modules and install everything again.

Debugging Metro errors

If everything else fails you might have to debug into Metro to see where the error is coming from. You can attach VSCode to Metro to debug where errors are coming from. Similar instructions to those in VS Code Debugging apply, summarized here for convenience

  1. code C:\rnw\node_modules\metro
  2. yarn start --max-workers 1 to start the bundler - this makes it easier to know what process to attach to
  3. In VSCode, attach to the node process:
    • Click on the ▶🐛 button, create a launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "Attach",
            "processId": "${command:PickProcess}"
        }
    ]
}
  1. F5 in VS Code to attach. Note: it's important that you attach to the bundler from VSCode before you launch the app - e.g. Playground - in VS.

  2. there will be two node processes:

    • yarn.js start --max-workers 1
    • ...\react-native\cli.js 👈 this is the one you want to attach to
  3. Breakpoints you'll want to set:

    • C:\rnw\node_modules\metro\src\lib\formatBundlingError.js - formatBundlingError
    • Search for the error string or a fragment of it, in the Metro codebase, to find points of interest.