nx icon indicating copy to clipboard operation
nx copied to clipboard

Getting `Cannot resolve @babel/runtime/helpers/interopRequireDefault` while initial setup of expo with nx

Open sandheep45 opened this issue 2 years ago • 4 comments

Current Behavior

Unable to spin up expo server with freshly created nx monorepo using command pnpx create-nx-workspace --pm pnpm --workspaceType=package-based

Screenshot from 2023-10-27 22-18-28

Screenshot from 2023-10-27 22-20-36

Screenshot from 2023-10-27 22-21-56

Expected Behavior

To start expo server with nx start <project>

GitHub Repo

No response

Steps to Reproduce

  1. Init nx monorepo using pnpx create-nx-workspace --pm pnpm --workspaceType=package-based command
  2. Filling up command as shown in the image Screenshot from 2023-10-27 22-18-28
  3. Navigate into the directory cd shopnest
  4. Fix unmet package version using pnpm nx install mobile --fix
  5. Starting up expo server pnpm nx start mobile

Nx Report

NX   Report complete - copy this into the issue template

   Node   : 18.18.2
   OS     : linux-x64
   pnpm   : 8.9.2
   
   nx                 : 17.0.2
   @nx/js             : 17.0.2
   @nx/jest           : 17.0.2
   @nx/linter         : 17.0.2
   @nx/eslint         : 17.0.2
   @nx/workspace      : 17.0.2
   @nx/detox          : 17.0.2
   @nx/devkit         : 17.0.2
   @nx/eslint-plugin  : 17.0.2
   @nx/expo           : 17.0.2
   @nx/react          : 17.0.2
   @nrwl/tao          : 17.0.2
   @nx/web            : 17.0.2
   @nx/webpack        : 17.0.2
   typescript         : 5.1.6


### Failure Logs

```shell
error: Error: Cannot resolve @babel/runtime/helpers/interopRequireDefault
    at /home/sandheep/projects/personal/shopnest/node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_@[email protected]_@[email protected]_ixupc4dnoyqo63cnmrjaebhgma/node_modules/@nx/expo/plugins/metro-resolver.js:30:15
    at resolveRequest (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/@[email protected][email protected]/node_modules/@expo/cli/build/src/start/server/metro/withMetroResolvers.js:50:24)
    at Object.resolve (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro-resolver/src/resolve.js:47:12)
    at ModuleResolver.resolveDependency (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:79:31)
    at DependencyGraph.resolveDependency (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/node-haste/DependencyGraph.js:277:43)
    at Object.resolve (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/lib/transformHelpers.js:169:21)
    at Graph._resolveDependencies (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/DeltaBundler/Graph.js:473:35)
    at Graph._processModule (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/DeltaBundler/Graph.js:261:38)
    at async Graph._traverseDependenciesForSingleFile (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/DeltaBundler/Graph.js:249:5)
    at async Promise.all (index 0)
    at async Graph.initialTraverseDependencies (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/DeltaBundler/Graph.js:233:5)
    at async DeltaCalculator._getChangedDependencies (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/DeltaBundler/DeltaCalculator.js:229:25)
    at async DeltaCalculator.getDelta (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/DeltaBundler/DeltaCalculator.js:112:16)
    at async DeltaBundler.buildGraph (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/DeltaBundler.js:54:5)
    at async IncrementalBundler.buildGraphForEntries (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/IncrementalBundler.js:66:19)
    at async IncrementalBundler.buildGraph (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/[email protected]/node_modules/metro/src/IncrementalBundler.js:146:19)
› Stopped server

Package Manager Version

pnpm --version 8.9.2

Operating System

  • [ ] macOS
  • [X] Linux
  • [ ] Windows
  • [ ] Other (Please specify)

Additional Information

I am using Ubuntu 23.10

sandheep45 avatar Oct 27 '23 17:10 sandheep45

Doesn't work with pnpm at this stage, had to use npm unfortunately.

medv avatar Dec 17 '23 07:12 medv

Any update on this one? @medv is pnpm really the issue here?

mansdahlstrom1 avatar Jan 27 '24 18:01 mansdahlstrom1

@mansdahlstrom1 The issue is with pnpm via metro. Here is a fix that worked for me:

Add node-linker=hoisted to .npmrc at the root of your monorepo, remove your node modules and do a pnpm install. Additionally, make a copy of that .npmrc in each of your expo apps directories so that EAS build can use the same pnpm config. You would also want to pin the node and pnpm versions in each of your expo apps' eas.json to the ones you are using in development, their docs explain how to do this and it is crucial to avoid further issues.

This works with expo@49 using the following in metro.config.js:

unstable_enableSymlinks: false,
unstable_enablePackageExports: false,

expo@50 uses a newer metro that has targeted some pnpm fixes, so this will either be unnecessary or will need to be revised and adjusted accordingly. If you find that this doesn't work for 50 but figure it out, drop a line here for the rest of us!

medv avatar Jan 28 '24 15:01 medv

thanks for the insight @medv. I ended up reverting moving to pnpm and went back to npm for now! Also I'm using React Native CLI not Expo.

mansdahlstrom1 avatar Jan 29 '24 10:01 mansdahlstrom1

@mansdahlstrom1 no worries, this issue was originally about expo but this should apply to anyone using metro with pnpm. Originally I went back to npm like you, but there is a reason I tried to revisit this again and again till I found the above solution, knowing it is temporary until metro evolves. Npm was just too slow in the end.

If you are using metro, update everything and follow metro's changelog/issues over the last couple of months - there are relevant improvements there. Meanwhile, the above (.npmrc containing node-linker=hoisted and the two experimental features set to false in metro config) should work for you if you are on an older version of metro. AFAIK they formalized enableSymlinks and automatically enabled it which could impact this, or remove the entire need for hoisting, but I could be imagining it.

Will be looking into this within the next month, so will try to remember to return here and update (unless somebody beats me to it ;))

ps. expo now went out of their way to document using bun, so have a try? For me, it successfully installed everything extremely quickly, and it actually ran the expo app with no immediately observed issues. Not sure why this would not apply to non-expo projects, but I am out of my depth here.

medv avatar Feb 01 '24 01:02 medv

expo 50 with pnpm no longer requires hoisted dependencies, however still exhibits other issues. Bun workspaces work out of the box so far with the following metro.config.ts (note I am executing expo directly with bun, you will have to change this to .js and replace import with require and export default with module.exports = config)

import { getDefaultConfig } from '@expo/metro-config'
import { mergeConfig } from 'metro-config'
import * as path from 'path'

const projectRoot = path.join(__dirname)
const workspaceRoot = path.join(__dirname, '..', '..')

const base = getDefaultConfig(projectRoot)
const config = mergeConfig(base, {
  projectRoot: projectRoot,
  resolver: {
    unstable_enableSymlinks: true,
    unstable_enablePackageExports: true,
  },
  watchFolders: [path.join(workspaceRoot)],
})

export default config

If you are using expo-router with either pnpm or bun, metro will not resolve package.json "main": "expo-router/entry". Instead the old way of "main": "index.js" that just contains import 'expo-router/entry' works well. There are still these teething issues with expo+metro left that don't quite end at what I've covered, but it's certainly more than usable and may save you a lot of time and effort compared to a nx integrated monorepo. I've decided to simply use workspaces with a good tsconfig setup instead of nx for now and it is much more breezy. We will get back into nx soon, but not in an integrated monorepo style, because the downsides are too numerous.

medv avatar Feb 09 '24 01:02 medv