parcel
parcel copied to clipboard
Autoinstall gets confused by symlinks and things break badly
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 toshared/uploads/image.jpg
- Then it tries to resolve
sharp
from the image's absolute path, which obviously fails, becausenode_modules
andpackage.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.