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
Add option to not follow symlinks #1819
Conversation
I added the opt-in option and added a test. It is also based on #1820 so all plugins can also read this option. |
fac76c2
to
a66dffc
Compare
Is there a CLI flag for this setting without needing a config file? I can't get it to work. |
@kzc I forgot about the CLI when I wrote this. It is just a config. |
In light of this description it's surprising that Rollup has the "realpath" node module resolution symlink behavior by default. It seems to be a bug. This PR should not be needed if Rollup behaved as described. The node |
Agreed this sounds like a bug to me. The default behaviour should ideally match Node resolution which would not be to use realpath, and rather have that be through a flag or plugin. |
@Rich-Harris Was the use of node's Line 13 in ddb698c
|
I can't recall to be honest, perhaps I was dealing with some tricky |
Perhaps we can consider then making This option could then either be |
@guybedford Would that be an acceptable breaking change? |
I find the phrase "to match node" to be a bit ambiguous. At the risk of restating what you wrote, I suggest by default Rollup should behave like (Off topic: I wish that node flag had been named |
Thanks @kzc for the clarifications and sorry for the confusion here, I got this the wrong way around then. In that case, this PR exactly as it stands sounds like exactly the right approach to me, as the Node behaviour should be the default followed behaviour. |
Respectfully, I beg to differ. I think by default Rollup should not use "realpath" as this PR does. "realpath" should be an explicit opt-in. Regardless of the default chosen, a Rollup CLI flag should be added to enable or disable "realpath" resolution. |
Ugh, I will make sure to think before typing here! Comment removed for inaccuracies until I can actually take the time to put together a coherent thought :P |
@guybedford No worries. The entire topic of "preserve symlinks" and node "realpath" module resolution is very confusing in general. |
So my the last deleted comment was on track with the arguments, I just got the wrong interpretation of symlink handling in NodeJS. Basically, NodeJS follows symlinks to their real paths because when you link packages in a development workflow, you need to get the guarantee that the linked package dependencies will be used, so that multi-version between linked projects works. Rollup should follow NodeJS here so that this same invariant is maintained when running Rollup in linking workflows this way. This PR implements So my recommendation is to merge this as-is. Apologies for confusions :) |
@guybedford Just to confirm, did you mean the following? "This PR implements Node in its default mode uses "realpath" module resolution (not to be confused with absolute path). If Although I happen to disagree with the default chosen by this PR to retain "realpath" module resolution by default, I would still recommend this PR implement a command line flag to override this "realpath" behavior globally rather than having it solely settable via rollup config. |
@kzc I'll do that once consensus is made on whether it is opt-in or opt-out. |
Whatever @guybedford decides for default behavior is fine with me. No doubt some Rollup projects are relying on the default "realpath" module resolution behavior. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of comments in the code.
I'm tending towards saying we should make preserveSymlinks opt-in exactly as we have here to continue match both NodeJS and other bundlers.
But I'd still be open to discussing use cases further here as to what is best for Rollup. The defaults seem to be set to building "libraries" which may benefit from symlinks. But ideally I'd like to see the defaults all matching NodeJS for easier first-use (even including NodeJS resolution and CommonJS plugin). Although I can hear @Rich-Harris rolling his eyes at this already...
src/utils/first.ts
Outdated
return candidates.reduce((promise, candidate) => { | ||
return promise.then( | ||
result => | ||
result != null ? result : Promise.resolve(candidate(...args)) | ||
result != null ? result : Promise.resolve(candidate.apply(this, args)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these changes intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It comes from #1820 (which should be merged first IMO). It is so plugins that also do realpath (multi-entry, node-resolve) can read the option via this.preserveSymlinks
and act accordingly, instead of each having their own duplicate options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also needed for https://github.com/rollup/rollup/pull/1819/files#diff-9b4fdd2a9bd0304295b89fa6270add84R54 to have this
context.
src/utils/mergeOptions.ts
Outdated
@@ -74,6 +74,7 @@ export default function mergeOptions ({ | |||
cache: getInputOption('cache'), | |||
preferConst: getInputOption('preferConst'), | |||
experimentalDynamicImport: getInputOption('experimentalDynamicImport'), | |||
preserveSymlinks: config.preserveSymlinks, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getInputOption
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(as far as I can tell this would enable --preserveSymlinks
in CLI but I may be reading this wrong?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to get the CLI option working. Is there some special syntax required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you build with getInputOption('preserveSymlinks')
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. I thought you were referring to the code as it exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to getInputOption
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be willing to merge this PR if it were not for the use of this
to access the bundle options. Unfortunately this works against any efforts to further unify the plugin API with regard to the this
context.
Currently, the transform
hook uses the context to enable plugins to throw warnings via this.warn
. IMO, this should be extended to all hooks to resolve #1501. Any PR that works towards this goal would be heartily welcomed.
For the problem at hand, however, replacing the context is totally unnecessary. Instead, the signature of resolveId
in defaults.ts
could be changed to
export function resolveId ({ preserveSymlinks }) { // possibly other options as well
return (importee: string, importer: string) => {
...
// previous implementation that now has direct access to options
}
}
as when the function is used in Graph.ts
, options are already available and can be used for currying. As for external plugins, they could always use the options
hook. Additionally, we could consider adding the inputOptions
to the context as well even though, as I pointed out above, this is not necessary at all for the current problem.
So to sum it up:
- Do not expose the bundle via context to gain access to options
- Instead, either use currying (less invasive for now and certainly easier to implement) or implement a more consistent plugin API as outlined above
I will take out the dependency on the |
37c55d6
to
0a5796b
Compare
rebased, and used curried options to remove dependency on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@kellyselden Just checked your test and it does not turn red if I change the "preserveSymlinks" option. Which is probably because git did not restore any symlinks for me. As the answers here sound like this should actually work, could you please check on your side that the symlink is actually correctly checked in? |
@lukastaegert Fixed the test. When I rebased in Windows, it must have destroyed the symlink... |
It's working now, thanks 👍 |
I believe symlinks used to be preserved, but now are followed. This is hurting me because in broccolijs land, everything is a symlink. This makes using the node-resolve plugin a nightmare.
Can we discuss an opt-in option for preserving symlinks? This PR is just a sample of what would change, not a final product. I would like the option to by system-wide public API, because several rollup plugins also follow rollup's example and follow symlinks. It would be nice if they could inherit the public option.