facebook / metro

🚇 The JavaScript bundler for React Native
https://metrobundler.dev
MIT License
5.25k stars 626 forks source link

unstable_enableSymlinks does not seems to work #1142

Open clauderobi opened 1 year ago

clauderobi commented 1 year ago

Description

I have this project structure

projectRoot -> node_modules/ -> src/ ... -> neWeb/ <- The intention is for this directory to be a symlink

I am getting this error message Unable to resolve module ./neWeb/hello.js

However, if I replace the symlink with a real directory, the error goes away

I did a quick search on the https://reactnative.dev with the _unstableenableSymlinks key word but only found the announcement. Hopefully, the intent of the feature is similar to my use case.

React Native Version

0.72.7

Output of npx react-native info

info Fetching system and libraries information... System: OS: Linux 6.2 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish) CPU: (24) x64 AMD Ryzen 9 5900X 12-Core Processor Memory: 3.79 GB / 46.94 GB Shell: version: 5.1.16 path: /bin/bash Binaries: Node: version: 16.13.0 path: ~/.nvm/versions/node/v16.13.0/bin/node Yarn: Not Found npm: version: 8.1.0 path: ~/.nvm/versions/node/v16.13.0/bin/npm Watchman: version: 20231001.212519.0 path: /usr/local/bin/watchman SDKs: Android SDK: Not Found IDEs: Android Studio: Not Found Languages: Java: version: 11.0.20.1 path: /usr/bin/javac Ruby: Not Found npmPackages: "@react-native-community/cli": Not Found react: installed: 18.2.0 wanted: 18.2.0 react-native: installed: 0.72.7 wanted: 0.72.7 npmGlobalPackages: "react-native": Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: Not found newArchEnabled: Not found

Steps to reproduce

1 - Init a standard project 2 - Configure metro.config.js with unstable_enableSymlinks, as in the following const config = { resolver: { unstable_enableSymlinks: true, }, }; 3 - Add the required import 4 - npm start -- --reset-cache 5 - Type a to run on Android

Snack, screenshot, or link to a repository

The imported file is hello.js and simply have the following code.

export function dummy () {
  let result = 'Hello';

  return result;
}

And the default App.ts was modified to have

import { dummy } from './neWeb/hello.js';
debugger;
const a = dummy();
console.log(a);
debugger;

Github repo with the defect. https://github.com/clauderobi/rn_Symlink

clauderobi commented 1 year ago

Ok, I created the git repo;

https://github.com/clauderobi/rn_Symlink

It is configured to use a symLink and it fails the build.

robhogan commented 1 year ago

Hi @clauderobi - unstable_enableSymlinks is documented in Metro's docs - see in particular the notes on watchFolders and how files behind symlinks must still be under watch.

You're almost there, but you need to add your workspace root, or at least the neWeb directory, to watchFolders, something like:

  const path = require('path');
  const config = { resolver: { unstable_enableSymlinks: true, }, watchFolders: [path.resolve(__dirname, '..')] };

Let us know if that doesn't help. (And thanks for the quality report with repro! 👍 )

clauderobi commented 1 year ago

Ok, now it works. But the whole concept only partially help me....

I have a very (like in very very very) naive way of dealing with shared JS source files. (*to be precise, between 3 WebApp, webpack, and now a react-native app). I simply have an extra repo with the shared source and symlink neWeb to it in the various sandboxes. The shared repo is somewhere outside of the 3 app's sansboxes.

webpack is able to cope with just allowing it to follow the symlinks. And to make things easier, webpack treats '/' as the project root directory so my imports always start with '/neWeb.....'

I was hoping to do the same with my react-native app; for this I added babel-plugin-root-import to handle the '/'. Now. the new symlink enables me to create my neWeb symlink. But, unless I am mistaken, the watchFolder configuration requires a real path. This somewhat defeats the idea of using a symlink in order to make the project configuration agnostic vs where the sandboxes are located.

I understand that monorepo was the main driver for this but I do not believe in monorepos (I do not think this is the place to discuss why here). An alternative is git submodule and subtree; but both are just nightmare....

The release note for when symlinlk was introduced talks about collecting developer experience. Being able for metro to follow symlinks too would be great!

robhogan commented 1 year ago

Appreciate the feedback @clauderobi

"Follow symlinks" can mean a bunch of different things - in Metro's case, the whole file system structure (under projectRoot/watchFolders) is loaded into memory during startup, and Metro is (now) able to internally represent symlinks and "traverse" them during resolution (for example, to resolve require('../neWeb/foo.js')), without performing additional I/O. There are no calls to realpath in Metro's resolver.

That is unusual compared to other bundlers which generally just read the filesystem on demand, but it allows Metro to operate on the very largest codebases and get transform cache hits, and perform resolutions, given only a cacheable snapshot of file metadata, without reading unmodified source files at all. That architecture works especially well on codebases that may be too large to check out on a laptop, but it does make simple-sounding features like following symlinks to unknown parts of the filesystem more difficult. We are working to improve the devx around this though - for example, so that Metro can discover these external dependencies on startup and automatically watch them.

Regarding the / feature - I can see how that'd be handy especially if you're not using workspaces (where @my-monorepo/neWeb/foo.js provides similar ergonomics). We have no plans to implement that at the moment, but you could do so in a custom resolver - maybe worth looking into if you have an unusual setup. Even so though, all resolution targets must be watched right now.

clauderobi commented 1 year ago

Thanks for the long feedback @robhogan

The '/' is handled Ok by babel...

Adding the path of the symlink in watchFolders work (sort of see, below); I was hoping that it would be possible to it via the symlink itself. Is that possible?

I am not able to access a source file located somewhere under the symlink.

The file I played with for the last few days had no import itself. I am now working with files where import statements exist but it does not work. The message I am getting is: Unable to resolve module @babel/runtime/helpers/interopRequireDefault from /neWeb/neCommon/api/apiCrypto.js

If I copy everything from the symlink under the project umbrella (i.e remove the symlink and create a normal directory) all works so the problem is definitely related to the symlink and watchFolders.

It appears that the issue is with node_modules since import of my source files works.

Here is what is in metro.config.js

const config = {
  resolver: {
    unstable_enableSymlinks: true,
  },
  watchFolders: [
    path.resolve(__dirname, '../../../NearEDGE/neWeb'),
  ]
};

node_modules is at the correct place, in the project directory, where metro.config.js and packahe.json, etc) is located.

watchman find . and watchman find ../../../NearEDGE/neWeb works as expected (after I resolved the inotify limits in the kernel).

I also deleted /tmp/metro-* and used npm start -- --reset-cache

(And, @babel/runtime/xxxx is indeed present in the FS).

robhogan commented 1 year ago

Ah, thanks for the report - this is a subtle known issue that typically comes up in non-monorepo shared code. Metro's transformation process injects dependencies on @babel/runtime/helpers to your code, and then when transforming that file's dependencies we see those as any other require() and try to resolve them relative to the file being transformed, in this case, from somewhere under neWeb, which won't find your project's dependencies.

Two possible workarounds: install @babel/runtime as a dependency of neWeb (assuming it has a package.json) or an ancestor, or add a custom resolver to resolve @babel/runtime relative to your project instead of relative to the source location.

This has come up a few times now, I'll prioritise fixing it in Metro. Thanks for the additional info.

clauderobi commented 1 year ago

My neWeb library does not have any package.json file it is just plain functional code that rely on the project to do everything else.

I try the custom resolver route. My first attempt was with this metro.config.js

const config = {
  resolver: {
    unstable_enableSymlinks: true,
    resolveRequest: (context, moduleName, platform) => {
      if (moduleName.startsWith('@babel/runtime')) {
        return {
          filePath: __dirname + '/node_modules/@babel/runtime/regenerator/index.js',
          type: 'sourceFile',
        };
      }
      return context.resolveRequest(context, moduleName, platform);
    }      

  },
  watchFolders: [
    path.resolve(__dirname, '../../../NearEDGE/neWeb'),
  ]
};

The syntax is all good since the project works well when neWeb is actually a regular directory (as a test). The resolver is obviously not needed, I just wanted to check things first. If I restore the symlink for neWeb, then I get the following in the debugger (so the project compiles, etc.)

_$$REQUIRE(...) is not a function

I was thinking that node_modules/@babel/runtime/regenerator/index.js would be the main entry point and everything else would follow. I guess not...

I try chaging the startWith and returnign the corresponding file for the actual file that was been looked at (node_modules/@babel/runtime/helpers/interopRequireDefault.js) but then other files are popping up.

Is it possible to have the resolver to inject a folder rather than complete file path?

robhogan commented 1 year ago

I think you can let the existing resolver do almost all of the work here, but the key is to change the origin it's resolving from so that it won't walk up the file tree from your source (where it won't find any installed dependencies).

    resolveRequest: (context, moduleName, platform) => {
      if (moduleName.startsWith('@babel/runtime')) {
        return context.resolveRequest({...context, originModulePath: __filename}, moduleName, platform);
      }
      return context.resolveRequest(context, moduleName, platform);
    } 

Or, maybe a cleaner approach - add your project's node_modules to nodeModulesPaths so that it's always used as a fallback.

(The downside to this in general - not a problem in your case - is that if you happen to have an incompatible version of @babel/runtime installed in your other "project", that'll still take precedence. nodeModulesPaths will only be used if regular resolution fails.)

config = {
  resolver: {
    nodeModulesPaths: [path.join(__dirname, 'node_modules')]
  }
}
clauderobi commented 1 year ago

Yes, the nodeModulesPaths approach is simpler and works. Should the issue be closed or stay open until a fix is available?

clauderobi commented 1 year ago

@robhogan Sorry for adding into this thread as the issue is indirectly related to unstable_enableSymlinks.

I am trying to setup a new project and I still having issues with the symlink. The reported error is: error: Error: Unable to resolve module, the path listed is correct.

metro.config.js in the new project is identical to the same in the old project, except for the adjustment to the watchFolders array.

The watchman configuration, as reported by watchman watch-list is correct. The root paths are all as they should be.

I am using babel to alter the path in some way but replacing the defective import statement path with an absolute full path fix the resolution issue for that import statement. This tells me that watchman in indeed Ok but the symlink setup is somehow invalid. But of course I have tons of import statement later that fail. I did this check just to make sure babel was not in the way (in any case, babel.config.js for both the old and the new project are identical).

I am under the impression that resolver.unstable_enableSymlinks is not taken into account. To make a long story short (well, shorter... ) in the end I did a grep for unstable_enableSymlinks for both the old and new projects. In the old project, there are a lot of hits under node_modules. But significantly less for the new project.

I won't list all the differences but of particular note, the following directories do not exist in the new project. node_modules/metro-config/node_modules node_modules/@react-native/metro-config/node_modules node_modules/@react-native-community/cli-plugin-metro/node_modules/metro-config

Another difference is that in the following 2 files, the value for unstable_enableSymlinks is true in the old project but false in the new. I di dnot make the change myself. node_modules/metro-config/src/defaults/index.js.flow node_modules/metro-config/src/defaults/index.js

package.json in the old project does not list anything that explains the difference in node_modules. Doing rm -rf node_modules and running npm i makes not difference.

I exhausted all I can think of. Any suggestion?

robhogan commented 1 year ago

That looks like you have multiple copies of metro-config, in a mix of older and newer versions. With RN 0.72.x, the default for unstable_enableSymlinks should be false, you shouldn't have any new Metro versions in there.

Could you paste the output of npm why @react-native/metro-config and npm why metro-config?

clauderobi commented 1 year ago

New project - Symlinks not working

@react-native/metro-config@0.72.11 dev
node_modules/@react-native/metro-config
  dev @react-native/metro-config@"^0.72.11" from the root project

and

metro-config@0.76.8
node_modules/metro-config
  metro-config@"0.76.8" from @react-native-community/cli-plugin-metro@11.3.10
  node_modules/@react-native-community/cli-plugin-metro
    @react-native-community/cli-plugin-metro@"11.3.10" from @react-native-community/cli@11.3.10
    node_modules/@react-native-community/cli
      @react-native-community/cli@"11.3.10" from react-native@0.72.7
      node_modules/react-native
        react-native@"0.72.7" from the root project
        peer react-native@"*" from @react-native/virtualized-lists@0.72.8
        node_modules/@react-native/virtualized-lists
          @react-native/virtualized-lists@"^0.72.8" from react-native@0.72.7
        peer react-native@"*" from @react-navigation/elements@1.3.21
        node_modules/@react-navigation/elements
          @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from @react-navigation/native@6.1.9
        node_modules/@react-navigation/native
          @react-navigation/native@"^6.1.9" from the root project
          peer @react-navigation/native@"^6.0.0" from @react-navigation/elements@1.3.21
          node_modules/@react-navigation/elements
            @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer @react-navigation/native@"^6.0.0" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from @react-navigation/native-stack@6.9.17
        node_modules/@react-navigation/native-stack
          @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from react-native-aes-gcm-crypto@0.2.2
        node_modules/react-native-aes-gcm-crypto
          react-native-aes-gcm-crypto@"^0.2.2" from the root project
        peer react-native@"*" from react-native-fast-rsa@2.4.0
        node_modules/react-native-fast-rsa
          react-native-fast-rsa@"^2.4.0" from the root project
        peer react-native@"*" from react-native-safe-area-context@4.7.4
        node_modules/react-native-safe-area-context
          react-native-safe-area-context@"^4.7.4" from the root project
          peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/elements@1.3.21
          node_modules/@react-navigation/elements
            @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from react-native-screens@3.27.0
        node_modules/react-native-screens
          react-native-screens@"^3.27.0" from the root project
          peer react-native-screens@">= 3.0.0" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
  metro-config@"0.76.8" from @react-native/metro-config@0.72.11
  node_modules/@react-native/metro-config
    dev @react-native/metro-config@"^0.72.11" from the root project
  metro-config@"0.76.8" from metro@0.76.8
  node_modules/metro
    metro@"0.76.8" from @react-native-community/cli-plugin-metro@11.3.10
    node_modules/@react-native-community/cli-plugin-metro
      @react-native-community/cli-plugin-metro@"11.3.10" from @react-native-community/cli@11.3.10
      node_modules/@react-native-community/cli
        @react-native-community/cli@"11.3.10" from react-native@0.72.7
        node_modules/react-native
          react-native@"0.72.7" from the root project
          peer react-native@"*" from @react-native/virtualized-lists@0.72.8
          node_modules/@react-native/virtualized-lists
            @react-native/virtualized-lists@"^0.72.8" from react-native@0.72.7
          peer react-native@"*" from @react-navigation/elements@1.3.21
          node_modules/@react-navigation/elements
            @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from @react-navigation/native@6.1.9
          node_modules/@react-navigation/native
            @react-navigation/native@"^6.1.9" from the root project
            peer @react-navigation/native@"^6.0.0" from @react-navigation/elements@1.3.21
            node_modules/@react-navigation/elements
              @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer @react-navigation/native@"^6.0.0" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from react-native-aes-gcm-crypto@0.2.2
          node_modules/react-native-aes-gcm-crypto
            react-native-aes-gcm-crypto@"^0.2.2" from the root project
          peer react-native@"*" from react-native-fast-rsa@2.4.0
          node_modules/react-native-fast-rsa
            react-native-fast-rsa@"^2.4.0" from the root project
          peer react-native@"*" from react-native-safe-area-context@4.7.4
          node_modules/react-native-safe-area-context
            react-native-safe-area-context@"^4.7.4" from the root project
            peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/elements@1.3.21
            node_modules/@react-navigation/elements
              @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from react-native-screens@3.27.0
          node_modules/react-native-screens
            react-native-screens@"^3.27.0" from the root project
            peer react-native-screens@">= 3.0.0" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
    metro@"0.76.8" from metro-config@0.76.8
    metro@"0.76.8" from metro-transform-worker@0.76.8
    node_modules/metro-transform-worker
      metro-transform-worker@"0.76.8" from metro@0.76.8

Old project (for reference) - Where symlinks work

@react-native/metro-config@0.72.11 dev
node_modules/@react-native/metro-config
  dev @react-native/metro-config@"^0.72.11" from the root project

and

metro-config@0.76.8
node_modules/@react-native-community/cli-plugin-metro/node_modules/metro-config
  metro-config@"0.76.8" from @react-native-community/cli-plugin-metro@11.3.10
  node_modules/@react-native-community/cli-plugin-metro
    @react-native-community/cli-plugin-metro@"11.3.10" from @react-native-community/cli@11.3.10
    node_modules/@react-native-community/cli
      @react-native-community/cli@"11.3.10" from react-native@0.72.7
      node_modules/react-native
        react-native@"0.72.7" from the root project
        peer react-native@"*" from @react-native/virtualized-lists@0.72.8
        node_modules/@react-native/virtualized-lists
          @react-native/virtualized-lists@"^0.72.8" from react-native@0.72.7
        peer react-native@"*" from @react-navigation/elements@1.3.21
        node_modules/@react-navigation/elements
          @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from @react-navigation/native@6.1.9
        node_modules/@react-navigation/native
          @react-navigation/native@"^6.1.9" from the root project
          peer @react-navigation/native@"^6.0.0" from @react-navigation/elements@1.3.21
          node_modules/@react-navigation/elements
            @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer @react-navigation/native@"^6.0.0" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from @react-navigation/native-stack@6.9.17
        node_modules/@react-navigation/native-stack
          @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from react-native-aes-gcm-crypto@0.2.2
        node_modules/react-native-aes-gcm-crypto
          react-native-aes-gcm-crypto@"^0.2.2" from the root project
        peer react-native@"*" from react-native-fast-rsa@2.4.0
        node_modules/react-native-fast-rsa
          react-native-fast-rsa@"^2.4.0" from the root project
        peer react-native@"*" from react-native-safe-area-context@4.7.4
        node_modules/react-native-safe-area-context
          react-native-safe-area-context@"^4.7.4" from the root project
          peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/elements@1.3.21
          node_modules/@react-navigation/elements
            @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@"*" from react-native-screens@3.27.0
        node_modules/react-native-screens
          react-native-screens@"^3.27.0" from the root project
          peer react-native-screens@">= 3.0.0" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
        peer react-native@">=0.40.0" from react-native-tcp@3.3.2
        node_modules/react-native-tcp
          react-native-tcp@"^3.3.2" from the root project

metro-config@0.76.8 dev
node_modules/@react-native/metro-config/node_modules/metro-config
  metro-config@"0.76.8" from @react-native/metro-config@0.72.11
  node_modules/@react-native/metro-config
    dev @react-native/metro-config@"^0.72.11" from the root project

metro-config@0.80.1
node_modules/metro-config
  metro-config@"^0.80.1" from the root project
  metro-config@"0.80.1" from metro@0.80.1
  node_modules/metro-config/node_modules/metro
    metro@"0.80.1" from metro-config@0.80.1
    metro@"0.80.1" from metro-transform-worker@0.80.1
    node_modules/metro-config/node_modules/metro-transform-worker
      metro-transform-worker@"0.80.1" from metro@0.80.1

metro-config@0.76.8
node_modules/metro/node_modules/metro-config
  metro-config@"0.76.8" from metro@0.76.8
  node_modules/metro
    metro@"0.76.8" from @react-native-community/cli-plugin-metro@11.3.10
    node_modules/@react-native-community/cli-plugin-metro
      @react-native-community/cli-plugin-metro@"11.3.10" from @react-native-community/cli@11.3.10
      node_modules/@react-native-community/cli
        @react-native-community/cli@"11.3.10" from react-native@0.72.7
        node_modules/react-native
          react-native@"0.72.7" from the root project
          peer react-native@"*" from @react-native/virtualized-lists@0.72.8
          node_modules/@react-native/virtualized-lists
            @react-native/virtualized-lists@"^0.72.8" from react-native@0.72.7
          peer react-native@"*" from @react-navigation/elements@1.3.21
          node_modules/@react-navigation/elements
            @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from @react-navigation/native@6.1.9
          node_modules/@react-navigation/native
            @react-navigation/native@"^6.1.9" from the root project
            peer @react-navigation/native@"^6.0.0" from @react-navigation/elements@1.3.21
            node_modules/@react-navigation/elements
              @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer @react-navigation/native@"^6.0.0" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from @react-navigation/native-stack@6.9.17
          node_modules/@react-navigation/native-stack
            @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from react-native-aes-gcm-crypto@0.2.2
          node_modules/react-native-aes-gcm-crypto
            react-native-aes-gcm-crypto@"^0.2.2" from the root project
          peer react-native@"*" from react-native-fast-rsa@2.4.0
          node_modules/react-native-fast-rsa
            react-native-fast-rsa@"^2.4.0" from the root project
          peer react-native@"*" from react-native-safe-area-context@4.7.4
          node_modules/react-native-safe-area-context
            react-native-safe-area-context@"^4.7.4" from the root project
            peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/elements@1.3.21
            node_modules/@react-navigation/elements
              @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@"*" from react-native-screens@3.27.0
          node_modules/react-native-screens
            react-native-screens@"^3.27.0" from the root project
            peer react-native-screens@">= 3.0.0" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
          peer react-native@">=0.40.0" from react-native-tcp@3.3.2
          node_modules/react-native-tcp
            react-native-tcp@"^3.3.2" from the root project
    metro@"0.76.8" from metro-config@0.76.8
    node_modules/@react-native-community/cli-plugin-metro/node_modules/metro-config
      metro-config@"0.76.8" from @react-native-community/cli-plugin-metro@11.3.10
      node_modules/@react-native-community/cli-plugin-metro
        @react-native-community/cli-plugin-metro@"11.3.10" from @react-native-community/cli@11.3.10
        node_modules/@react-native-community/cli
          @react-native-community/cli@"11.3.10" from react-native@0.72.7
          node_modules/react-native
            react-native@"0.72.7" from the root project
            peer react-native@"*" from @react-native/virtualized-lists@0.72.8
            node_modules/@react-native/virtualized-lists
              @react-native/virtualized-lists@"^0.72.8" from react-native@0.72.7
            peer react-native@"*" from @react-navigation/elements@1.3.21
            node_modules/@react-navigation/elements
              @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer react-native@"*" from @react-navigation/native@6.1.9
            node_modules/@react-navigation/native
              @react-navigation/native@"^6.1.9" from the root project
              peer @react-navigation/native@"^6.0.0" from @react-navigation/elements@1.3.21
              node_modules/@react-navigation/elements
                @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
                node_modules/@react-navigation/native-stack
                  @react-navigation/native-stack@"^6.9.17" from the root project
              peer @react-navigation/native@"^6.0.0" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer react-native@"*" from @react-navigation/native-stack@6.9.17
            node_modules/@react-navigation/native-stack
              @react-navigation/native-stack@"^6.9.17" from the root project
            peer react-native@"*" from react-native-aes-gcm-crypto@0.2.2
            node_modules/react-native-aes-gcm-crypto
              react-native-aes-gcm-crypto@"^0.2.2" from the root project
            peer react-native@"*" from react-native-fast-rsa@2.4.0
            node_modules/react-native-fast-rsa
              react-native-fast-rsa@"^2.4.0" from the root project
            peer react-native@"*" from react-native-safe-area-context@4.7.4
            node_modules/react-native-safe-area-context
              react-native-safe-area-context@"^4.7.4" from the root project
              peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/elements@1.3.21
              node_modules/@react-navigation/elements
                @react-navigation/elements@"^1.3.21" from @react-navigation/native-stack@6.9.17
                node_modules/@react-navigation/native-stack
                  @react-navigation/native-stack@"^6.9.17" from the root project
              peer react-native-safe-area-context@">= 3.0.0" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer react-native@"*" from react-native-screens@3.27.0
            node_modules/react-native-screens
              react-native-screens@"^3.27.0" from the root project
              peer react-native-screens@">= 3.0.0" from @react-navigation/native-stack@6.9.17
              node_modules/@react-navigation/native-stack
                @react-navigation/native-stack@"^6.9.17" from the root project
            peer react-native@">=0.40.0" from react-native-tcp@3.3.2
            node_modules/react-native-tcp
              react-native-tcp@"^3.3.2" from the root project
    metro@"0.76.8" from metro-config@0.76.8 dev
    node_modules/@react-native/metro-config/node_modules/metro-config
      metro-config@"0.76.8" from @react-native/metro-config@0.72.11
      node_modules/@react-native/metro-config
        dev @react-native/metro-config@"^0.72.11" from the root project
    metro@"0.76.8" from metro-transform-worker@0.76.8
    node_modules/metro-transform-worker
      metro-transform-worker@"0.76.8" from metro@0.76.8
    metro@"0.76.8" from metro-config@0.76.8
robhogan commented 1 year ago

It looks like the difference is that your old project has metro-config@"^0.80.1" in its package.json, which is pulling in all of Metro 0.80.

It may be that your new project is hitting a bug in Metro 0.76 that's fixed in Metro 0.80, but I'd need more detail on what's failing to resolve and what the project structure is to determine that. It's not obviously a symlink-related issue, as far as I can tell.

clauderobi commented 1 year ago

I did npm i --save metro-config (I do not recall doing it in the old project, probably something did it for me under the hood).

But no difference, I still get Error: Unable to resolve module (I did the rm -rf /tmp/metro-* drill and npm start -- --reset-cache).

Now, grep -r unstable_enableSymlinks * return the same thing for both the old nad new project. In node_modules/metro-config/src/defaults/index.js.flow and node_modules/metro-config/src/defaults/index.js, unstable_enableSymlinks is not set to true.

The structure is as follow

- neWeb
- <project>
  - neWeb (the symlink)
  - ....

In metro.config. js, I have

 ...
  resolver: {
    unstable_enableSymlinks: true,
    nodeModulesPaths: [
      path.join(__dirname, 'node_modules'),
  },
  watchFolders: [
    path.resolve(__dirname, '../neWeb'),
  ],
 ... 

Output from watchman watch-list

{
    "version": "20231001.212519.0",
    "roots": [
        "<edited>/neWeb",
        "<edited>/grantor"
    ]
}

If I replace the neWeb symlink with a real directory hierarchy (using cp -a) all is good.

clauderobi commented 11 months ago

@robhogan

Sorry for the delay, I was pulled to something else. I am not back at trying to solve the problem with resolving modules that are access via the symlink.

To eliminate problem with watchman I did this test:

stopping (ctrl-c) the metro bundler
watchman watch-del-all  
watchman watch-list
// Restarting the bundler (npm start)
watchman watch-list
watchman find <edited>/neWeb | grep api  

The watch-list shows empty for the first invocation and then the folders I configured in (Using path.resolve) for the 2nd. watchman find listed my files.

Then I ran the following command

npx metro get-dependencies ./src/test.js

and got the Error: Unable to resolve module result.

(metro version, as reported by the cli, is 0.76.8)

In package.json, I have the 2 modules: "metro-config": "^0.80.1", "@react-native/metro-config": "^0.72.11",

Both the project which works and the new project have the same thing. I redid an npm install on the new.

Any suggestion on how to proceed here?

Thanks.