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

--preserve-symlinks should (optionally?) apply to the require.main module #19383

Closed
dgoldstein0 opened this issue Mar 16, 2018 · 11 comments
Closed

Comments

@dgoldstein0
Copy link
Contributor

dgoldstein0 commented Mar 16, 2018

  • Version: 8.9.3
  • Platform: Linux
  • Subsystem: module loading

From #9673:

--preserve-symlinks does preserve symlinks for all require() calls, but strangely not that of the entry.js file passed on node's command line.

This still seems to be the case today: it is impossible to get node to preserve symlinks for the entry point file. A quick demo of today's behavior:

// a.js
console.log("problem");
// entry.js
require("./a");
// app/a.js
console.log("no problem");

symlink app/entry.js -> entry.js

Then run node --preserve-symlinks app/entry.js.

What I expected: "no problem" printed
What actually happens: "problem" printed

--

This is a problem for me because I am supporting node integration with bazel (Google's open source build system), and bazel generates binaries by building all the files, and creating a symlink tree for each binary that gives it access to all the files it needs; our bazelled node binaries need --preserveSymlinks so that they resolve modules relative to the symlink, and not to the target of the symlink. While we've worked around the problem, our workaround breaks require.main and module.parent among others, so code that works under vanilla node won't work in our bazelled binaries. The exact details are documented here: https://github.com/dropbox/rules_node#node_binary - the BAZEL_NODE_MAIN_ID hack is our workaround, which imo is rather ugly.

If either:
a) --preserve-symlinks applied the same to the entry point as all other modules
b) there was an extra flag to enable the same symlink preserving behavior for the entry point

Then we could remove this hack and have better compatibility with existing npm modules.

@dgoldstein0
Copy link
Contributor Author

fwiw I suspect that the main module is treated specially to support symlinks like node_modules/.bin/tsc. Possibly we could special case those to follow exactly one level of symlinks, but all other cases we do the standard preserve-symlinks behavior (when the flag is passed, that is). Or just keep it simple and allow e.g. a --preserve-symlinks-main that will apply the --preserve-symlinks behavior to the main file, and leave .bin/ special cases up to the caller to figure out.

@guybedford
Copy link
Contributor

@dgoldstein0 looking at the code this does seem to be quite intentional, although I'm not sure what the intended use case was for this.

node_modules/.bin sounds like a good reasoning though to me.

Interestingly we don't do this in the ES module resolver, so this makes me think we should probably follow the same actually. So while unrelated, thanks for bringing awareness to this :)

@guybedford
Copy link
Contributor

Looking through the discussion at #6537 I can't actually seem to find any good reason for skipping preserveSymlinks for the main entry point actually.

I'd be interested to hear what others think here as it would be nice to ensure consistency with the ES loader - should we try make preserveSymlinks work for the main, or bring this behaviour into the ES resolver?

//cc @jasnell

@dgoldstein0
Copy link
Contributor Author

bump. any updates on this? did it get lost in other people's inboxes?

@guybedford
Copy link
Contributor

@dgoldstein0 in putting together #19388 I did review #6537 quite closely on this question, and as far as I can tell at https://github.com/nodejs/node/pull/6537/files#diff-d1234a869b3d648ebfcdce5a76747d71L116 this is a very deliberate feature likely for supporting Node bins.

Changing such a thing would these use cases as well as break backwards compatibility, so I don't see that it would be that possible at this point.

But there may be deeper arguments to be made here.

@dgoldstein0
Copy link
Contributor Author

dgoldstein0 commented Mar 28, 2018 via email

@guybedford
Copy link
Contributor

@dgoldstein0 as I say I'm not sure there's a way to do that without breaking existing .bin cases with --preserveSymlinks at this point. Perhaps you could describe your use case here a little further?

@dgoldstein0
Copy link
Contributor Author

dgoldstein0 commented Mar 28, 2018 via email

@guybedford
Copy link
Contributor

Right, I get what you mean. Are you proposing a --preserve-symlinks-main flag or similar then? Perhaps the best route forward is to create a PR and then see how that fares in review. I'm not sure how I feel about it personally.

@dgoldstein0
Copy link
Contributor Author

dgoldstein0 commented Mar 31, 2018 via email

@vsemozhetbyt
Copy link
Contributor

Closed in 2365965

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