informatom

informatom

I have set up Tailwindcss for a Phoenix (v 1.5.8, so using Webpack, Liveview and Surface) project successfully and tried to switch to the new tailwindcss/jit-Compiler. That does not fully work, as changes in a view or template file won’t get picked up. If I touch the tailwind config file manually, the compiler recompiles successfully. So my issue is the range of files, that are monitored by webpack.

Currently by watcher config looks like this (from dev.exs):

config :pan, PanWeb.Endpoint,
  http: [port: System.get_env("PORT") || 4000],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [
    node: [
      "node_modules/webpack/bin/webpack.js",
      "--mode",
      "development",
      "--watch-stdin",
      cd: Path.expand("../assets", __DIR__)
    ]
  ]

The tailwindcss/jit documentation stresses, that you set NODE_ENV=development, which should be done with --mode development, I hope.
Anybody knowing, what should be changed? I tried to remove the cd ../assets part, but then the webpack config is broken.

Showing Posts 1 to 10

Exadra37

Exadra37

In Linux the default value for watching for files changes is too low, especially for applications using Node :wink:

If you don’t have already installed inotify-tools, then install it now with:

sudo apt install inotify-tools

Next, check your inotify watcher limit:

cat /proc/sys/fs/inotify/max_user_watches

Mine is set to 524288, but 'ts already tweaked :slight_smile:

To increase it:

echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf

Then apply the new value:

sudo sysctl -p

Check its applied:

cat /proc/sys/fs/inotify/max_user_watches
informatom

informatom OP

Thanks for the quick replay, but inotify-tools was already installed and the watcher limit was already set to 524288.

Recompilation triggered by changes of templates works for Phoenix live view and they get recompiled by Elixir, so inotify works as expected. Just webpack seems not be notified about them.

I assume Webpack is somehow restricted to changes within the assets directory.

NobbZ

NobbZ

Yes, that’s where the npm project lives and therefore is assumed to be the source root by webpack.

APB9785

APB9785

Creator of ECSx

When I tried switching my Phoenix project from standard tailwind to tailwind JIT using the official instructions, it stopped generating new classes. Any classes that were already used in a previous version were available, but if I used a new class, there would be no effect, even after shutting down the server and recompiling. The dev team was unwilling to help troubleshoot because they don’t know Phoenix so I just went back to standard tailwind, which works great for me.

If anyone does manage to get JIT running with Phoenix, please let us know how (and maybe let the tailwind-JIT team know too so they can update the installation instructions for Phoenix users). The added features shown in the demo look fantastic.

informatom

informatom OP

My workaround is currently to touch the tailwind.config.js whenever I introduce a new class on mature projects. On rather new ones I go back to standard tailwind until the rate of new classes introduced is low enough, that touching is bearable.

soup

soup

The provided instructions are ok, I needed to write this change to fix a webpack issue:

and this repo has a working config for me:

Even with the webpack fix above, I still noticed one time I had to invalidate the css file’s hash to make it get new changes. I am 99% 90% on this being a webpack4 issue (or a dependency that can’t bump to latest because of phx locking to wb4). No issues after that though.

E:

Revisiting that repo, it still seems flakey. Really inconsistent bug, but I don’t get issues on my main project that uses JIT, which is using a config transplanted from this repo, so can’t say. E: Actually this may be something to do with using Temple in that project and the second compile step triggers watcher more reliably or something.

Basically it needs to be “warmed up” by invalidating the css hash and maybe banging a webpack/tailwind conf then after that it all seems to function as expected. I also run with NODE_ENV=development mix phx.server, but I also set that explicitly in my package.json scripts (which I remember now don’t get run because phx uses it’s own watcher). I don’t really have the bandwidth to debug the whole thing so it’s a bit of “thow spaghetti at wall”.

Note that --mode X and NODE_ENV=X are different. --mode just enables some changes in webpack it doesn’t filter down to other tools.

Possibly including some build cleaner on webpack run would solve these issues, so a fresh file is made every time you start it up.

soup

soup

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.

informatom

informatom OP

Thanks for all your explanation here!

Edit:

  • Introducing the blank line an app.css once is also necessary.
soup

soup

Yeah, it seems that after the hard source cache exists, you have to invalidate the css file hash at least once after sever boot. Then it seems to not need it again for that server for me.

IMO just dump the hard source plugin from your webpack config and see if you can live with with whatever performance penalty you get (none for me but I have very few js/css dependencies).

See webpack.config.js on GitHub - rktjmp/phx-tailwindcssjit: How to setup Phoenix Framework and TailwindCSS-JIT · GitHub

Another option is writing a mix task that rm’s the cache before running phx.server.

cnck1387

cnck1387

I have to wonder if it’s a Webpack 4 thing.

When I use Webpack 5 and the JIT compiler everything works great. I can add new classes to my HTML and the JIT picks it up, and I can add new classes to my app.css file and it works too. No need to restart the dev server or mess with the cache.

Also, I didn’t have to do anything extra in my webpack config but I do run the Webpack dev server in a separate process outside of Phoenix.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
widianto
I think I’ve found a small improvement I could contribute to <%= web_namespace %>.CoreComponents (installer/templates/phx_web/compo...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews