laravel / vite-plugin

Laravel plugin for Vite.
MIT License
790 stars 148 forks source link

No HMR in weird symlink scenario #284

Closed legecha closed 7 months ago

legecha commented 7 months ago

Vite Plugin Version

1.0.1

Laravel Version

10.44.0

Node Version

21.6.2

NPM Version

10.2.4

Operating System

Linux

OS Version

Ubuntu 20.04.6

Web browser and version

Safari Version 17.3 (19617.2.4.11.8)

Running in Sail?

No

Description

Certain symlinks break hmr file changes from being recognised. So far, I have only noticed pint.json but I presume it's other similar type config that Vite might recognise?

The weird thing here is that if I explicitly pass to the refresh option the refreshPaths array instead of true, but I remove "resources/lang/**" from that list, it works again.

Another possibly relevant point is that if I start npm run dev with a valid configuration/set of file then change them while it's running, the hmr file changes are still detected, so must be something at initial run.

FYI, the reason we had a pint.json symlink in the first place was to share Pint configuration across multiple projects.

Steps To Reproduce

https://github.com/legecha/vite-plugin-bug-report

See commits for examples of working and non-working states.

jessarcher commented 7 months ago

Very strange! Thanks for the repo - it helped me replicate the issue.

Regarding the resources/lang/** change - this directory doesn't exist by default, but I noticed that when I created the directory, the problem went away. I played around with this more and found that the issue only happens when a non-existing path inside the resources directory is added (e.g. resources/foo breaks it, app/foo doesn't). I don't think it's the resources directory specifically, just that the non-existing path shares a common parent with the app.css file being changed.

I also found that the symlink needs to be in the root directory of the project, but the file name doesn't seem to matter (e.g. a foo.bar symlink still triggers the issue).

We're using https://github.com/ElMassimo/vite-plugin-full-reload behind the scenes for the reload feature. After following the rabbit hole, the paths ultimately get passed to the add method on an instance of chokidar's FSWatcher that is instantiated by Vite. I've been able to replicate the issue by directly passing a non-existing path to Vite's chokidar instance so it doesn't seem to be anything specifically with vite-plugin-full-reload. I've also tried replicating the issue in a fresh Node project but can't seem to trigger it, even when instantiating chokidar with the same options that Vite uses.

I think the fix is to filter out non-existing refresh paths before passing them to vite-plugin-full-reload, as it's this plugin that's passing the potentially non-existing path.

jessarcher commented 7 months ago

Closing now that a fix PR (#285) is open.