If you run webpack separately, maybe the issue is clearer. Webpack has no idea when you alter templates because it doesn’t look at .html.exs
files (or in the lib/
) folder.
AFAICT, webpack4 can only / will only watch files that it finds via an entry point (which is why our JS file includes a imports a CSS file). I don’t think there is a good way to add an elixir template as an entry point.
TailwindJIT has it’s own watcher stuff I think, but I am not sure where it gets it’s file list from. Probably by piggybacking the purge
purge-css option in it’s config.
Why invalidating the root CSS file causes everything to start working, I am not sure.
Possibly:
Tailwind watcher runs as a child of webpack, but maybe doesn’t start automatically or doesn’t run on boot, or something.
webpack doesn’t see template changes in html.exs
files (no entry point).
changing the css file causes webpack to notice a css change.
tailwind watcher wake up, they do know to look at exs files because we tell it what to search for when it runs it’s purge-css stuff.
now tailwind watcher is awake and template changes propagate back out.
Maybe…
Edit:
There are a few moving parts:
TailwindCSS-jit works additively (in NODE_ENV=development) from an in memory cache (?).
Each time you restart the server and invalidate the css file, you get a fresh tw build.
This means:
- As you go through the “add class to html, invalidate css hash” workflow, the new class appears in the CSS, but the old class remains there.
- If you don’t restart the server, those old classes remain, even if they are no longer in your templates.
- When you do restart the sever but do not invalidate the hash, the old classes still hang around even if they are not in your templates.
- so they still “seem to work”, because the css still exists.
- Adding new classes to a template wont work until you invalidate the css, at which point the old but now unused classes disappear. Now it you try to use a “it worked before” class, it won’t work because it’s now a new class.
This is why it seems to work “some of the time” and why my main project seems immune to issues: (mostly) all the classes used in that project are already there.
On top of all this, there seems to be a race condition where you may be served the css file before tailwind has finished building it, so the hot reload may show no change but a hard reload will. This is most likely to occur if you use an expensive (?) class like a custom color.
Edit:
Basically, the TLDR is:
- Follow the phx-tailwindcssjit repo to setup TailwindCSS-jit (Mostly as per instructions except for the extra webpack4 patch).
- Start your server as
NODE_ENV=development mix phx.server
- Invalidate the main css entry point (Add a blank line to the end of app.css, save)
- Edit your templates as normal, repeat the invalidation every time you restart your server.
That should be reasonably reliable. Sometimes you may have to hard refresh the page if you hit the race condition.
Edit edit edit edit:
Probably it’s all rooted in HardSourceWebpackPlugin
.
A fresh clone of the repo will work flawlessly for me, no messing about with invalidating the css hash.
Stop the server, restart it and you have to start invalidating the hash.
rm -rf assets/node_modules/.cache/hard-source
and start the server and you have no issues again.
I don’t actually notice any real speed differences with the cache nuked, and hard source hasn’t been updated in a few years, possibly it’s out of style/not needed with modern js systems. Could probably just drop it from your webpack config if you want.