New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Packager] doesn't resolve modules that are symlinks #637

Closed
JaapRood opened this Issue Apr 3, 2015 · 114 comments

Comments

Projects
None yet
@JaapRood
Copy link

JaapRood commented Apr 3, 2015

As described in the browserify handbook you can use symlinks in the node_modules folder to reference modules. This is mainly useful for preventing ../../../../ requires.

With a symlink setup from the project root setup like:

ln -s src/app node_modules/app

in any file in the project you can:

var  app = require('app');
var somethingElse  = require('app/lib/something-else');

However, the packager can't resolve them: Requiring unkonwn module "app".

Edit:
Check out this repo to easily reproduce the error above:

https://github.com/JaapRood/react-native-packager-symlink-bug

@romanonthego

This comment has been minimized.

Copy link

romanonthego commented May 13, 2015

is it a bug or is it by design?
symlinks would be really handy actually :(

@cgarvis

This comment has been minimized.

Copy link

cgarvis commented May 16, 2015

Just ran into this trying to develop a npm library locally using npm link

@brentvatne brentvatne changed the title Packager doesn't resolve modules that are symlinks [Packager] doesn't resolve modules that are symlinks May 31, 2015

@amasad

This comment has been minimized.

Copy link
Contributor

amasad commented Jun 2, 2015

I thought we supported this use case. Thanks

@amasad amasad added the packager label Jun 2, 2015

@mars

This comment has been minimized.

Copy link

mars commented Jun 6, 2015

Perhaps related, relative requiring a module above the iOS/React Native directory fails the same way:

// in index.ios.js
var Auth = require('../common/auth');

Error: Requiring unknown module "../common/auth". If you are sure the module is there, try restarting the packager.

I tried symlinking that higher-level directory within the React Native project to fix, but it failed as well, leading me to this issue.

@JaapRood

This comment has been minimized.

Copy link
Author

JaapRood commented Jun 8, 2015

I finally had some time to make an example to prove it's not working. Check out this repo which references the example app component through a symlink, which doesn't get resolved.

https://github.com/JaapRood/react-native-packager-symlink-bug

Now, if only I had any idea on why.

@amasad

This comment has been minimized.

Copy link
Contributor

amasad commented Jun 15, 2015

I have an internal fix for this. Aiming to get it out next sync :)

@brentvatne

This comment has been minimized.

Copy link
Collaborator

brentvatne commented Jun 15, 2015

Awesome @amasad - looking forward to this, will make lib development easier

@JaapRood

This comment has been minimized.

Copy link
Author

JaapRood commented Jun 15, 2015

Great @amasad, that would be immensely helpful!

@romanonthego

This comment has been minimized.

Copy link

romanonthego commented Jun 25, 2015

@amasad no pressure, but when to expect next sync? :) will it be in 0.6.0 release?

@romanonthego

This comment has been minimized.

Copy link

romanonthego commented Jun 26, 2015

still an issues as to 0.6.0 and 0.7.0-rc ...

@amasad

This comment has been minimized.

Copy link
Contributor

amasad commented Jun 30, 2015

That's strange. I'll give @JaapRood's test project a spin see what the problem is.

@idmontie

This comment has been minimized.

Copy link

idmontie commented Jul 2, 2015

👍 Same problem here. Symlinks are very useful, especially when I don't want to make a node package just to share a component between two related React apps.

@romanonthego

This comment has been minimized.

Copy link

romanonthego commented Jul 3, 2015

it generally usefull for many global acessible parts of your application: constants, configs, reusable components replacing react-native base components (styled Text for example)
and none of other methods of requiring modules from applications root seen to work too :( this is why i'm hoping for this one so much.

@brentvatne

This comment has been minimized.

Copy link
Collaborator

brentvatne commented Jul 8, 2015

@amasad - any updates here?

@romanonthego

This comment has been minimized.

Copy link

romanonthego commented Jul 9, 2015

👍

@ide

This comment has been minimized.

Copy link
Collaborator

ide commented Jul 11, 2015

Figured out a little more about the cause -- the issue goes away when switching to the Node-based watcher instead of the Watchman-based one. The watchman homepage says, "Watchman does not follow symlinks. It knows they exist, but they show up the same as any other file in its reporting." so this could be the root case.

Support for symlinks seemed to get pretty strong pushback in facebook/watchman#105 so perhaps the packager could use a combination of Watchman for most files and the Node watcher for symlinked packages. npm linked packages reside in the first node_modules directory (you'd have to go out of your way to end up with node_modules/pkg1/node_modules/<linkedpkg>), so that might simplify things a little. I tried adding a --noWatchman option to the packager but ran into fd limit issues unfortunately.

The npm link workflow is really important for anyone developing a React Native module so I do think this is a priority for the external RN community.

@goatfish

This comment has been minimized.

Copy link

goatfish commented Jul 14, 2015

I'm not sure if this is related or not. I have a symlinked folder for some of my js files in the project root. These are some internal libraries that are part of another repo. I am importing them using require('./lib/file') where lib is a symlink to a folder. This is working in the packager in 0.7.1 and not working in 0.8.0-rc. I am using io.js.

I figured I'd put this here in case some code is changing in 0.8.0-rc related to this bug...

@brentvatne

This comment has been minimized.

Copy link
Collaborator

brentvatne commented Jul 21, 2015

@amasad - seems like this was working for some people in 0.7.1 and not in 0.8.0-rc, as reported in #2076

@xinthink

This comment has been minimized.

Copy link
Contributor

xinthink commented Jul 23, 2015

For 0.8.0-rc, the problem is Fastfs._getRoot returns null, when the local module located outside of the app dir, because the packager can only resolve modules within the app dir by default.

To solve the problem, I must launch the packager with an additional argument --root=<path_to_local_module>.

I'm not sure what's the best solution for this issue?

@zhaiduo

This comment has been minimized.

Copy link

zhaiduo commented Jul 29, 2015

I use 0.8.0, after close all terminal, xcode, restart. then everything is OK.

@JaapRood

This comment has been minimized.

Copy link
Author

JaapRood commented Aug 4, 2015

For those who have missed the release of 0.9.0-rc it's listed there as a known issue.

@bradens

This comment has been minimized.

Copy link
Contributor

bradens commented Aug 14, 2015

Is there any good workaround here?

@gethinwebster

This comment has been minimized.

Copy link

gethinwebster commented Aug 14, 2015

I've found that this can be worked around by uninstalling watchman and therefore forcing react native to use the default node file watcher, however this does have speed drawbacks, and you can come up against issues with the number of files being accessed depending on the project.

-------- Original message --------
From: Braden Simpson notifications@github.com
Date: 14/08/2015 20:25 (GMT+00:00)
To: facebook/react-native react-native@noreply.github.com
Cc: Gethin Webster gethin.webster@agilityworks.co.uk
Subject: Re: [react-native] [Packager] doesn't resolve modules that are symlinks (#637)

Is there any good workaround here?

Reply to this email directly or view it on GitHubhttps://github.com//issues/637#issuecomment-131214239.

@amasad

This comment has been minimized.

Copy link
Contributor

amasad commented Sep 8, 2015

Sorry for the delay, was out for a while.

@amasad - seems like this was working for some people in 0.7.1 and not in 0.8.0-rc, as reported in #2076

What happened is that we started using watchman for the filesystem crawling. My understanding is that watchman doesn't follow symlinks but should treat them like any other file. Which in theory should still work. I can try to debug this soon. Alternatively we can add an option to force not using watchman for filesystem crawling.

@Mokto

This comment has been minimized.

Copy link

Mokto commented Sep 27, 2015

Hi guys, any update on this ?

My only way to develop a react native library is to git clone my repo inside my node_modules, isn't it ?

@braunsquared

This comment has been minimized.

Copy link

braunsquared commented Apr 5, 2017

Hey guys,
I got tired with dealing with the symlink handling so I forked react-native and patched the packager to fix the issues I was having. This might not fix everyones issues but it has certainly fixed mine. The issue that I was having (and have had since the dawn of time in using react-native) was caused by the packagers inability of discovering peer dependencies on symlinked modules (npm link or yarn link). I've updated the resolver for the packager to be aware of the root paths of the project and automatically add these paths to the search query used to resolve modules. The prior implementation would try to be smart about resolving the paths based on the modules real path which breaks on symlinked modules.

Take it or leave it, but you are all welcome to use it. I've patched both the 0.42-stable branch and the 0.43-stable branch but haven't really tested 0.43 since it relies on an alpha version of react.

Github repo

To use 0.42-stable update package.json react-native dependency to:
"react-native": "https://github.com/braunsquared/react-native/tarball/b576d07039dfaa0045fcff8b463f7490a86a7465"

For 0.43-stable use:
"react-native": "https://github.com/braunsquared/react-native/tarball/843be3173f617de0e13fc219f1aa2a809b94d1a3"

@zandroid

This comment has been minimized.

Copy link

zandroid commented Apr 6, 2017

Not sure but probably node option --preserve-symlinks can help you somehow. https://nodejs.org/dist/latest-v6.x/docs/api/cli.html#cli_preserve_symlinks

I had similar problem with symlinked files/modules (but on regular node project) and this option resolves problems for me.

@ladas-larry

This comment has been minimized.

Copy link

ladas-larry commented Apr 11, 2017

We definitely need to find way how to run React Native Packager with --preserve-symlinks option.

@OscarGodson

This comment has been minimized.

Copy link

OscarGodson commented May 4, 2017

Any update on this? I was surprised to see npm and just normal *nix symlinks dont work at all

@kokokenada

This comment has been minimized.

Copy link

kokokenada commented May 4, 2017

+1

3 similar comments
@ittikorns

This comment has been minimized.

Copy link

ittikorns commented May 6, 2017

+1

@silentcloud

This comment has been minimized.

Copy link

silentcloud commented May 11, 2017

+1

@danidewitt

This comment has been minimized.

Copy link

danidewitt commented May 18, 2017

+1

@bleighb

This comment has been minimized.

Copy link

bleighb commented May 26, 2017

+1

@hramos

This comment has been minimized.

Copy link
Contributor

hramos commented Jun 1, 2017

Please avoid adding metoo +1 comments, as it distracts from the conversation. May I suggest using reactions instead?

@phil-r

This comment has been minimized.

Copy link

phil-r commented Jun 1, 2017

@hramos The main problem with reactions that they don't attract any attention, but I agree that seeing that many +1 is annoying.

@ivosabev

This comment has been minimized.

Copy link

ivosabev commented Jun 2, 2017

I hope it is annoying enough so they finally fix a 2 year old issue.

@ThaJay

This comment has been minimized.

Copy link

ThaJay commented Jun 2, 2017

probably not though
#9942

@bleighb

This comment has been minimized.

Copy link

bleighb commented Jun 2, 2017

This wasn't in the original post, but please note that this isn't some obscure feature request. npm link, for example, uses symbolic links behind the scenes, so it breaks with that too. I can confirm that copying, rather then symlinking, does work, however that becomes impractical when working on different npm packages locally.

Also, I tried it on macOS and linux and same issue occurs.

@skellock

This comment has been minimized.

Copy link
Contributor

skellock commented Jun 4, 2017

The RN packager was built for Facebook's needs; which unfortunately (for us) didn't include symlinks.

But... packager will be getting some love shortly. Hoping to see some news this week.

In the meantime:

  • Have a look at haul by the Callstack crew. Provided your symlink'd dependency doesn't have its own react-native dependency, this works really well. (if it does you can delete the files temporarily).
  • It is possible to stage some work out of node_modules again with live reloading. Yes, it's pretty derpy, but pair it with a file watcher and it's better than nothing.
@gary-lo

This comment has been minimized.

Copy link

gary-lo commented Jun 14, 2017

+1

@hramos

This comment has been minimized.

Copy link
Contributor

hramos commented Jun 14, 2017

Can you move this to https://github.com/facebook/metro-bundler now that the packager has been moved out of React Native?

@bleighb

This comment has been minimized.

Copy link

bleighb commented Jun 19, 2017

Hey guys I found a pretty good workaround: cp -al <sourceDirectory> <destinationDirectory>.

Basically because react-native doesn't respect symbolic links, the files need to be indistinguishable from the real files with hard links. The problem with hard links is that they don't work for directories. cp -al will copy the directory structure while using hard links for every file. Now I can go back to my local node package and transpile the source files like normal, and the changes in the build files are automatically refleted in the node_modules/ of my other package. 👌

@bleighb

This comment has been minimized.

Copy link

bleighb commented Jun 20, 2017

Update: this seems to only partially work. It does reflect the changes in my editor, for example, but react native won't notice the change until I 'save' the updated file (even though saving isn't changing the file contents).

@hramos

This comment has been minimized.

Copy link
Contributor

hramos commented Jun 20, 2017

Closing, please reopen in the metro-bundler repo.

@hramos hramos closed this Jun 20, 2017

@di

This comment has been minimized.

Copy link
Contributor

di commented Jun 20, 2017

See facebook/metro#1.

@fredbt

This comment has been minimized.

Copy link

fredbt commented Jun 21, 2017

+1 having the issue with npm link.
My use case is that I'm trying to share some code between two apps, so I'd have the following config:

-- app1
-- app2
-- shared

where I will writ components in the shared folder. I tried to use the idea from here: https://stackoverflow.com/questions/8088795/installing-a-local-module-using-npm
but when I ran npm start in app1 folder, it failed to load the bundles, even though I can see the symlink for "shared" in the node_modules of app1.

@hramos

This comment has been minimized.

Copy link
Contributor

hramos commented Jun 21, 2017

Locking conversation, now that this has been moved to facebook/metro#1.

@facebook facebook locked and limited conversation to collaborators Jun 21, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.