parcel icon indicating copy to clipboard operation
parcel copied to clipboard

Autoinstall gets confused by symlinks and things break badly

Open jahudka opened this issue 2 years ago • 1 comments

Hi everybody, I'm having an issue which I think might in part be a bug in Parcel, so I thought I'd ask and potentially report here. I have a somewhat involved setup, but I think I can figure out a reasonable approximation. Consider the following folder structure:

shared/
  uploads/
    image.jpg
releases/
  1/
    site/
      index.html
      uploads -> absolute symlink to shared/uploads
    node_modules/
    package.json
current -> absolute symlink to releases/1

The index.html file contains this: <img src="uploads/image.jpg?width=800">.

When I run parcel build "site/**/*.html" within current (which really means within releases/1), weird things happen. Some are quite understandable, some less so:

  • Parcel resolves uploads/image.jpg to the real absolute path to shared/uploads/image.jpg
  • Then it tries to resolve sharp from the image's absolute path, which obviously fails, because node_modules and package.json are on a different subtree of the project structure
  • Then it tries to autoinstall sharp and gets stuck on that

I understand everything that happens up to the moment Parcel tries autoinstalling sharp - it's logical why module resolution would need to resolve things relative to the real path of the source file instead of the symlink that led to it, and while it does throw quite a wrench in my setup, I'll figure out a way to work around it somehow (although I'm quite open to suggestions!).

But the really unsettling thing is what happens during the attempt to install sharp. Not only does the build get stuck, but something happens somewhere within there that causes my node_modules to get (at least partially) deleted - when I kill the Parcel build, I don't even have a parcel directory within node_modules anymore (and quite a few others are missing as well).

I've found this issue, which seems related, but it appears the consensus there is a rogue package.json somewhere up the directory tree - and I've checked for this, and found no such file on my system (nor package-lock.json, nor yarn.lock, nor node_modules, for that matter; neither in the tree leading up to the project directory, nor in $HOME). The Node installation on my system is owned by root and not writable for anyone else, so the npm install which Parcel is running behind the scenes can't be attempting to install the package globally (it would fail instantly if it did).

I don't know if there's anything to be done about this within Parcel, really - the only idea I had was that Parcel could attempt to resolve build tools like sharp from the current working directory, if resolving them from the file which needs them fails - and it could be argued that they're really a dependency of the build tool, ie. Parcel or one of Parcel's transformers, not the files they're supposed to work on - but I understand if that's not desirable. I thought I'd at least write this down in case somebody runs into the same issue. Again, if anyone has any tips on how to solve situations like these, I'm all ears!

Parcel: 2.8.3, NPM: 9.5.0, Node: 18.14.1, OS: Ubuntu Server 22.04, not that I think any of that matters in this situation.

EDIT: To be clear, the aspect I think might possibly be a Parcel bug is the fact that autoinstalling a dependency deletes files it shouldn't delete - I know it's very likely not Parcel itself doing that, but seeing as Parcel is triggering the process which is actually responsible, I think it is worth considering adding a check in Parcel for some of the common situations which might cause this to happen.

jahudka avatar Feb 21 '23 15:02 jahudka