facebook / metro

šŸš‡ The JavaScript bundler for React Native
https://metrobundler.dev
MIT License
5.16k stars 613 forks source link

Experimental symlink support not working for PNPM Monorepo #1042

Open brownieboy opened 1 year ago

brownieboy commented 1 year ago

Description

I have PNPM working with the new, experimental symlink support in RN 0.72.3. But it only works for me for a single RN package in a repo. It doesn't work for me in a Monorepo set up.

In my monorepo pnpm ios from the apps/app1 folder throws this error:

 BUNDLE  ./index.js

error: Error: Unable to resolve module react-native from /Users/michaelbrown/Development/test-rn72-pnpm-monorepo/apps/app1/index.js: react-native could not be found within the project or in these directories:
  node_modules
  ../../node_modules
  3 |  */
  4 |
> 5 | import {AppRegistry} from 'react-native';
    |                            ^
  6 | import App from './App';
  7 | import {name as appName} from './app.json';

pnpm android throws this error:

FAILURE: Build failed with an exception.

* Where:
Settings file '/Users/michaelbrown/Development/test-rn72-pnpm-monorepo/apps/app1/android/settings.gradle' line: 2

* What went wrong:
A problem occurred evaluating settings 'app1'.
> Could not read script '/Users/michaelbrown/Development/test-rn72-pnpm-monorepo/apps/app1/node_modules/@react-native-community/cli-platform-android/native_modules.gradle' as it does not exist.

react-native is in the apps/app1/node_modules folder, although it's a symlink (which is how PNPM works). That android/settings.gradle file also is there, and not as a symlink this time.

React Native Version

0.72.3

Output of npx react-native info

npx react-native info info Fetching system and libraries information... System: OS: macOS 13.3.1 CPU: (8) arm64 Apple M1 Memory: 68.48 MB / 16.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 18.9.0 path: ~/Library/Caches/fnm_multishells/87821_1689716195576/bin/node Yarn: version: 1.22.19 path: ~/Library/Caches/fnm_multishells/87821_1689716195576/bin/yarn npm: version: 8.19.1 path: ~/Library/Caches/fnm_multishells/87821_1689716195576/bin/npm Watchman: version: 2023.06.12.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.12.1 path: /Users/michaelbrown/.rvm/gems/ruby-3.0.0/bin/pod SDKs: iOS SDK: Platforms:

Steps to reproduce

mkdir test-rn72-pnpm-monorepo
cd test-rn72-pnpm-monorepo
mkdir apps
cd apps
npx react-native@latest init app1
cd app1
rm yarn.lock
rm -rf node_modules
cd ../..
npm init -y

Add new file, pnpm-workspace.yaml at root repo level:

packages:
  # all packages in direct subdirs of packages/
  - 'apps/*'

That file is required for PNPM monorepo support, as PNPM does not use the packages field in the package.json.

Run pnpm i to (re)install the dependencies.

Enable the experimental symlink support in file apps/app1/metro.config.js:

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

/**
 * Metro configuration
 * https://facebook.github.io/metro/docs/configuration
 *
 * @type {import('metro-config').MetroConfig}
 */
const config = {
  resolver: {
    unstable_enableSymlinks: true,
    unstable_enablePackageExports: true,
  },
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

Snack, code example, screenshot, or link to a repository

https://github.com/brownieboy/test-rn72-pnpm-monorepo

cortinico commented 1 year ago

Moving to metro

uxigene commented 1 year ago

Managed to get it working by adding watchFolders. Here is my config example:

const config = {
  watchFolders: [path.join(__dirname, '..', '..')],
  resolver: {
    unstable_enableSymlinks: true,
    unstable_enablePackageExports: true,
  },
};
brownieboy commented 1 year ago

@uxigene,

  watchFolders: [path.join(__dirname, '..', '..')],

Many thanks! Yes, that worked for me too šŸ˜Š, although I'm not sure why that works šŸ¤”.

You need to add the path import at the top of the file (metro.config.js) too, of course:

const path = require('path');
MartinDawson commented 11 months ago

This doesn't seem to work for me, same error as the above on android, even after clearing builds, cache etc, @brownieboy @uxigene please can you update the repo with the working builds.

Also, can you please say specifically what node version, pnpm version you are using.

It seems very flaky.

karlhorky commented 7 months ago

For those using Expo SDK 50 + RN 0.73 with pnpm, it seems there are other file resolution issues too: