lydell / elm-watch

`elm make` in watch mode. Fast and reliable.
https://lydell.github.io/elm-watch/
MIT License
155 stars 8 forks source link

watching through symlinks #93

Open BrianHicks opened 7 months ago

BrianHicks commented 7 months ago

Hey! I've got a weird bug. I haven't had success making an SSCCE, but maybe this will jump out at you since you know the code.

I have a pnpm workspace with a bunch of packages, some of which generate Elm code as part of our build system. elm-watch lives in another package which produces the JS artifact. Simplifying some, you can think of our directory layout as being this:

monorepo root
├── generated
│   ├── elm-icons
│   └── elm-types
└── packages
    └── frontend-elm

6 directories, 0 files

These are all packages, so the packages/frontend-elm package depends on generated/elm-icons, generated/elm-types, and some others. When you run pnpm i these get set up like this:

monorepo root
├── generated
│   ├── elm-icons
│   └── elm-types
└── packages
    └── frontend-elm
        └── node_modules
            └── generated
                ├── elm-icons -> generated/elm-icons
                └── elm-types -> generated/elm-types

(This is the output of tree, where -> means a symlink.)

This has mostly worked fine in the past: when we need to get the generated Elm code from some generated directory, we put node_modules/generated/elm-icons/build/elm or whatever in elm.json, the compiler follows the symlink, compiles the code, we're good.

But recently we noticed that changes to the generated files here don't trigger the file watcher in elm-watch. We'll regenerate code, or make some egregious error on purpose, and elm-watch totally ignores the change until we restart it.

I tried to replicate this with simple symlinks with no success… a setup like below works in the watcher:

.
├── bar -> foo
└── foo
    └── Foo.elm

So this seems to be some specific thing in how pnpm sets things up that doesn't work, but I can't figure out what it is! I thought it might be the fact that the real package names are like @project-generated/elm-icons but that seems to work fine in small samples!

For now, we can get around this by adding ../../generated/elm-icons/src/elm instead of going through node_modules, but that's brittle since it depends more on our directory layout instead of the package names.

Do you have any idea what could be happening here?

Running elm-watch@2.0.0-beta.2

lydell commented 7 months ago

Ugh, I hate symlinks 😅

I do have a couple of tests with symlinks, since I tried to handle them like the compiler does whenever I noticed some behavior. But I’ve never used symlinks with Elm for real.

There could be bugs in:

I don’t have much clues other than that. I would suggest diving deep into elm-watch’s code and see if you can figure something out.

lydell commented 1 month ago

I just realized something. I’ve configured the watcher to ignore any paths with /node_modules/ in it:

https://github.com/lydell/elm-watch/blob/8940e582d3af2d618bd9f7219b9d57724c2f8507/src/Hot.ts#L490

Maybe you can try commenting that out and see if changes then are picked up? If they do, we need to figure something out. We usually want to ignore everything in node_modules/, but not everything in your case.

BrianHicks commented 1 month ago

I'm no longer at Vendr. @Janiczek or @wolfadex may be able to get this filed, but using relative paths was working pretty well when I left!

wolfadex commented 1 month ago

Taking a look and I'm having trouble replicating this issue. I'll keep an eye out though and update if I find anything.