nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
22.62k stars 2.26k forks source link

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

Open sandheep45 opened 8 months ago

sandheep45 commented 8 months ago

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/@nx+expo@17.0.2_@expo+cli@0.10.14_@swc-node+register@1.6.8_@swc+core@1.3.95_@types+node@16.11_ixupc4dnoyqo63cnmrjaebhgma/node_modules/@nx/expo/plugins/metro-resolver.js:30:15
    at resolveRequest (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/@expo+cli@0.10.14_expo-modules-autolinking@1.5.1/node_modules/@expo/cli/build/src/start/server/metro/withMetroResolvers.js:50:24)
    at Object.resolve (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro-resolver@0.76.7/node_modules/metro-resolver/src/resolve.js:47:12)
    at ModuleResolver.resolveDependency (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:79:31)
    at DependencyGraph.resolveDependency (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/node-haste/DependencyGraph.js:277:43)
    at Object.resolve (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/lib/transformHelpers.js:169:21)
    at Graph._resolveDependencies (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/DeltaBundler/Graph.js:473:35)
    at Graph._processModule (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/DeltaBundler/Graph.js:261:38)
    at async Graph._traverseDependenciesForSingleFile (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/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/metro@0.76.7/node_modules/metro/src/DeltaBundler/Graph.js:233:5)
    at async DeltaCalculator._getChangedDependencies (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/DeltaBundler/DeltaCalculator.js:229:25)
    at async DeltaCalculator.getDelta (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/DeltaBundler/DeltaCalculator.js:112:16)
    at async DeltaBundler.buildGraph (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/DeltaBundler.js:54:5)
    at async IncrementalBundler.buildGraphForEntries (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/IncrementalBundler.js:66:19)
    at async IncrementalBundler.buildGraph (/home/sandheep/projects/personal/shopnest/node_modules/.pnpm/metro@0.76.7/node_modules/metro/src/IncrementalBundler.js:146:19)
› Stopped server

Package Manager Version

pnpm --version 8.9.2

Operating System

Additional Information

I am using Ubuntu 23.10

medv commented 6 months ago

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

mansdahlstrom1 commented 5 months ago

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

medv commented 5 months ago

@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!

mansdahlstrom1 commented 5 months ago

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.

medv commented 5 months ago

@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 commented 4 months ago

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.