metro
metro copied to clipboard
Experimental symlink support not working for PNPM Monorepo
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: - DriverKit 22.4 - iOS 16.4 - macOS 13.3 - tvOS 16.4 - watchOS 9.4 Android SDK: API Levels: - "29" - "30" - "31" - "32" - "33" Build Tools: - 29.0.2 - 30.0.2 - 30.0.3 - 31.0.0 - 32.0.0 - 32.1.0 - 33.0.0 System Images: - android-29 | Google APIs Intel x86 Atom_64 - android-31 | Google APIs ARM 64 v8a - android-31 | Google Play ARM 64 v8a - android-32 | Google APIs ARM 64 v8a - android-32 | Google Play ARM 64 v8a Android NDK: Not Found IDEs: Android Studio: 2021.3 AI-213.7172.25.2113.9123335 Xcode: version: 14.3.1/14E300c path: /usr/bin/xcodebuild Languages: Java: version: 11.0.11 path: /usr/bin/javac Ruby: version: 3.0.0 path: /Users/michaelbrown/.rvm/rubies/ruby-3.0.0/bin/ruby npmPackages: "@react-native-community/cli": Not Found react: installed: 18.2.0 wanted: 18.2.0 react-native: installed: 0.72.3 wanted: 0.72.3 react-native-macos: Not Found npmGlobalPackages: "react-native": Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: true newArchEnabled: false
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
Moving to metro
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,
},
};
@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');
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.
For those using Expo SDK 50 + RN 0.73 with pnpm, it seems there are other file resolution issues too:
- https://github.com/expo/expo/issues/22413#issuecomment-1913169577