GithubHelp home page GithubHelp logo

Comments (7)

samsnori avatar samsnori commented on September 21, 2024

Workaround

For now, I'm creating a mount point which solves this issue.

Great thing about this solution is that you don't have to change any of the configs either.

cd <home>/main-app
cd app
mkdir shared-lib-mounted

sudo mount --bind ../../shared-lib shared-lib-mounted

I'm very curious why symlinks aren't working though. I'm sure it turns out to be something silly

from metro.

robhogan avatar robhogan commented on September 21, 2024

Hi @samsnori - thanks for the report and particularly for all the detail here.

Could you clarify what import you're using in your JS/TS source, or what you'd like that to look like?

I'm also curious about the use of extraNodeModules - normally the values there would be expected to be directories containing package.json files (ie, valid packages). It sounds like you might be wanting to use something like import {Button} from 'shared-package', or are you just using relative paths and it's not working when the relative path includes a symlink?

from metro.

samsnori avatar samsnori commented on September 21, 2024

Hi @robhogan thanks for you reply. In my shared-lib directory, I've got a couple of JS files that I like to use across projects. These do not belong to a package so there is no index.js or package.json. E.g. for this test I created a file shared-lib/src/components/Button.jsx which contains:

/* ------------------------------------------------------- */

import { View, Text } from 'react-native';

/* ------------------------------------------------------- */

function Button(props) {
  return (
    <View>
      <Text>This is my fake button</Text>
    </View>
  );
}

/* ------------------------------------------------------- */

export {
  Button
};

Then I would like to import this anywhere in my main-app like:

import { Button } from 'shared-lib/components/Button'

This works when I use a plain directory (or mount point) but not when using a symlink. This is why I suspect that the symlink is causing this.

Tbh, the extraNodeModules is something that I copied from one of the many articles I found about this. I haven't tested if things will work when I remove this, I wouldn't think so, but I'll do a test.

from metro.

robhogan avatar robhogan commented on September 21, 2024

Interesting, thanks - tbh I’m surprised that works at all without a package.json, but the inconsistency is surprising in any case. An import that isn’t a relative or absolute file path should only resolve under those settings if it begins with a package name.

I don’t think we’ve done a lot of testing on the interaction between extraNodeModules and symlinks, what you’re seeing does seem like a bug one way or another. I’ll see if I can reproduce.

from metro.

vitorsilvalima avatar vitorsilvalima commented on September 21, 2024

Even more weird,

I have the following dependencies in my shared-lib and it does not work at all giving the following error:

Error: Unable to resolve module @babel/runtime/helpers/asyncToGenerator from /Users/vitorsilvalima/projects/diggy/packages/core/node_modules/zod/lib/helpers/parseUtil.js:

"dependencies": {
    "dayjs": "1.10.8",
    "mongoose": "^6.7.5",
    "zod": "^3.22.4"
  }

However, it works if I remove zod or if I install babel-runtime in my shared-lib which makes no sense at all.

from metro.

samsnori avatar samsnori commented on September 21, 2024

Yes, I've experienced that too. The state of RN tooling is extremely sad.

To be honest I think the issue is not entirely the fault of Metro, it's the whole "npm" / package / tooling space. The biggest flaw I see which causes -a lot- of these issues, is that each bundler or packager has it's own module resolution solutions. NPM should have provided a solution that could be used by bundlers instead.

It's also good to realize that Metro is most likely not going to spend time on this; the very first issue that was posted already mentioned similar issues. I understand the main developers have other priorities.

For me, I found a solution which "works" but is ugly.

from metro.

stefang42 avatar stefang42 commented on September 21, 2024

Even more weird,

I have the following dependencies in my shared-lib and it does not work at all giving the following error:

Error: Unable to resolve module @babel/runtime/helpers/asyncToGenerator from /Users/vitorsilvalima/projects/diggy/packages/core/node_modules/zod/lib/helpers/parseUtil.js:

"dependencies": {
    "dayjs": "1.10.8",
    "mongoose": "^6.7.5",
    "zod": "^3.22.4"
  }

However, it works if I remove zod or if I install babel-runtime in my shared-lib which makes no sense at all.

I just ran into a similar issue in my project, where I include a module (with package.json, etc.) from an external path. I got Metro to include it by using resolver.extraNodeModules, but it wouldn't use the other dependencies from the local node_modules. After lots of searching, trial & error (and swearing, lots of swearing) I finally found a solution that works (at least for me):

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

const path = require("path");

const myExtraModuleDir = path.resolve(__dirname, "../../myExtraModule");
const extraNodeModules = {
  'myExtraModule': myExtraModuleDir,
};
const watchFolders = [
  // Include extra module dir to work around Metro's bug where resolver.extraNodeModules
  // does not work without corresponding watchFolders, see also
  // https://github.com/facebook/metro/issues/834
  myExtraModuleDir
];

const config = {
  watchFolders: watchFolders,
  resolver: {
    extraNodeModules: new Proxy(extraNodeModules, {
      get: (target, name) =>
        // redirects dependencies referenced from myExtraModule/ to local node_modules
        name in target ? target[name] : path.join(process.cwd(), `node_modules/${name}`),
    }),
    // unstable_enableSymlinks: true,  // defaults to true since Metro v0.79.0
  },
  resetCache: true,  // https://metrobundler.dev/docs/configuration/#resetcache
};

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

That "Proxy" part did the trick, inspired by this StackOverflow thread: Metro extraNodeModules does not work - Error: Unable to resolve module.

Seriously, this really should be easier and more straightforward.

from metro.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.