Skip to content
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

esbuild doesn't follow symlinks #698

Closed
whaaaley opened this issue Jan 21, 2021 · 7 comments
Closed

esbuild doesn't follow symlinks #698

whaaaley opened this issue Jan 21, 2021 · 7 comments

Comments

@whaaaley
Copy link

whaaaley commented Jan 21, 2021

I think this was changed because of one of these issues #154 or #310. However, this makes it really difficult to use esbuild with monorepos and it's unexpected because other tools follow symlinks.

I know this has been a hot issue with node's module resolution. See nodejs/node-eps#46 and the threads linked there. The argument for resolving symlinks has to do with supporting alternative package managers like pnpm. The argument against this is that it's not what other languages do as mentioned here nodejs/node#3402 (comment).

From what I understand the solution they reached was adding --preserve-symlinks and --preserve-symlinks-main because they were in too deep to revert something like that. Or at least that's what they were claiming. Info on the flags here: https://nodejs.org/dist/latest-v14.x/docs/api/cli.html#cli_preserve_symlinks

In any case, my preference would be to preserve the symlink location. This is what symlinks were intended for and messing with them because of a few unofficial package managers seems wrong. Symlinks should behave as if the files/directory is actually there where the link is. Support for alternative package managers could be solved through a plugin instead.

Thanks for reading 👋

EDIT: This actually might not be the issue I'm having. Looks like symlinks work when they're within the project but as soon as they're linked outside the project directory symlinks break.

@whaaaley
Copy link
Author

I actually can't reproduce this issue outside my project so I'm closing this issue until I can figure it out.

@ricklamers
Copy link

Are there any plans to support something similar to the --preserve-symlinks flag? Without it our build setup doesn't work since it would require having all dependencies of symlinked imports in the real symlinked location (instead of at the location where the symlink itself is located).

@whaaaley
Copy link
Author

whaaaley commented Jan 27, 2021

@ricklamers I tested this thoroughly last week and can confirm that esbuild follows relative softlinks correctly, at least on version 0.8.34. I think I misunderstood what was being discussed in the referenced issues above. I would quadruple check that your symlinks are pointing the the right spot. I spent a day and a half debugging symlink issues myself only to learn that my symlink was pointing to the wrong place the whole time. I kept getting tripped up because when creating links with ln the path is not relative to where you're running the command from it's relative to where you're placing the link.

In my monorepo I have a shared dir that sits in the root of the repo. The path would be /shared. Then I have a relative softlink located in apps/appname/src/shared where shared is the link. The symlink path is ../../../shared.

@ricklamers
Copy link

@whaaaley the symlinks are being correctly resolved. The problem however is the follow (citing node.js docs here):

By default, when Node.js loads a module from a path that is symbolically linked to a different on-disk location, Node.js will dereference the link and use the actual on-disk "real path" of the module as both an identifier and as a root path to locate other dependency modules. In most cases, this default behavior is acceptable. However, when using symbolically linked peer dependencies, as illustrated in the example below, the default behavior causes an exception to be thrown if moduleA attempts to require moduleB as a peer dependency:

 ├── app
 │   ├── index.js
 │   └── node_modules
 │       ├── moduleA -> {appDir}/moduleA
 │       └── moduleB
 │           ├── index.js
 │           └── package.json
 └── moduleA
     ├── index.js
     └── package.json

https://nodejs.org/api/cli.html#cli_preserve_symlinks

So a flag for esbuild that has the same resolving behaviour as node.js with the --preserve-symlinks flag would allow the demonstrated peer dependencies to work.

@whaaaley
Copy link
Author

whaaaley commented Jan 27, 2021

@ricklamers Ah you're right, my bad. I agree with you. In my project I had to inline the modules I was importing from the symlinked location, which was a bit ugly. A flag for this would be nice.

@ricklamers
Copy link

@evanw should I open a separate issue for this?

@evanw
Copy link
Owner

evanw commented Feb 7, 2021

Sure. Please ideally provide a reproducible test case demonstrating the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants