PepsRyuu / nollup

Rollup compatible development bundler for fast rebuilds and HMR.
MIT License
488 stars 28 forks source link

Symlink handling is inconsistent #211

Open charlag opened 3 years ago

charlag commented 3 years ago

When some part of the code is behind a symlink (e.g. file: url in package.json) then compiling this code will resolve module IDs to be real filesystem path. However when symlink path is passed to invalidate() of the bundle the symlink is not resolved so the file in question will not be invalidated and rebuilding will not work.

Easy fix would be to call fs.realpath() from onAddWatchFile().

PepsRyuu commented 3 years ago

Just so I understand it fully, do you have the steps / code on how to reproduce this? What OS is this running on as well?

charlag commented 3 years ago

Hey It's Linux. I tried to create a reproducer but so far I could not achieve it. Here's the scenario: in one of our projects we depend on another of our projects. Normally they are linked via package.json and commit hash but when we develop locally we put file:../path/to/project in package.json as a version. This makes npm create a symlink inside node_modules like node_modules/some_project -> ../some_project. We are setting up a chokidar watcher on that node_modules/some_project. Events which we are getting from chokidar have the symlink in them (so the path in the event is /path/to/another_project/node_modules/some_project/some_file). But nollup has registered some files in NollupContext.files as not having a symlink (as path/to/some_project/some_file) so when we call invalidate on the path with node_modules inside of it nothing happens because it doesn't match what Nollup is tracking internally.

I can't seem to reproduce it because with simple example Nollup still tracks file via the symlink and I don't know how to influence it. Here's some code where I try to reproduce it (but do not succeed): https://github.com/tutao/nollup-bug/tree/symlink

PepsRyuu commented 3 years ago

Does your original code in which you're encountering this problem, resolve the symlink using something like fs.realpath before passing it into invalidate()? Is there potentially a plugin doing some something before calling addWatchFiles?

Question comes down to whether both invalidate() and addWatchFile() should internally resolve the symlink as much as possible using fs.realpath. I don't think it will cause issues. Would be good if you can confirm if the above is what is happening in your code before proceeding to any fix.