srid / ema

Change-aware static site generator for Haskell programmers
https://ema.srid.ca
GNU Affero General Public License v3.0
115 stars 9 forks source link

Tailwind helper: support for compiling CSS #20

Open srid opened 3 years ago

srid commented 3 years ago

Instead of using the twind shim, which requires JS and thus

... we should try a windicss like approach in "compiling" the classes from generated HTML into the final minified CSS. The tailwind helper can provide both options.

(Might as well explore writing a type-safe Haskell wrapper for Tailwind, as a stretch goal)

srid commented 3 years ago

There is now twind cli, https://github.com/tw-in-js/twind-cli#twindcli

srid commented 3 years ago

Using https://github.com/srid/tailwind-nix

find . -name \*.html| xargs -d '\n'  windicss

generates a windi.css that can be retroactively referenced in the generated HTML. Since spawning the windicss node program is slow, we should do this only during 'ema generate', and continue to use CDN in dev server mode.

srid commented 3 years ago

Could use https://github.com/tweag/inline-js to evaluate nodeJS code.

billksun commented 3 years ago

Not sure if this helps, but TailwindCSS v2.1 comes with a JIT compiler.

IHP also was able to integrate TailwindCSS into it's framework. Have to do an npm install but it wasn't too difficult to setup.

srid commented 3 years ago

@billksun My understanding is that TailwindCSS's official CLI does not have a mode where you can ask it "here's a list of HTML files; can you dump the compiled and merged CSS for it?".

In windicss, twind/cli - you can do this in a straightforward manner (see https://github.com/srid/emanote/issues/58#issuecomment-859953912), without having to touch JavaScript (like the need to create & manage a tailwind.config.js).

(Ideally I'd get rid of windicss/twind too; but that will need us to develop a pure Haskell compiler for tailwind, which will also come in handy for live-server integration in Ema so that CDN need not be used anymore)

srid commented 3 years ago

Tailwind 2.2.0 got released, but some of its new features work only in JIT, which means it won't work with Ema's live server as that uses CDN. That sucks, and it is all the more reason to do a complete port of Tailwind to pure Haskell and use that from Ema.

https://github.com/tailwindlabs/tailwindcss/releases/tag/v2.2.0

srid commented 3 years ago

For the record, emanote solved this by using windicss to compile the CSS from generated HTML files,

https://github.com/srid/emanote/blob/master/default/_emanote-bin/compile-css

srid commented 2 years ago

Now that Tailwind 3.0 is released, it just might be better to use the official compiler (thus requiring nodes), and use https://tailwindcss.com/blog/tailwindcss-v3#play-cdn for live server (assuming it works like twind does).

EDIT: Play CDN is actually noticeably slower.

srid commented 2 years ago

A demo of using Tailwind 3.0 for Ema sites here: https://github.com/srid/banyan/pull/5 (works in both live server and static site modes)

Basically, run the Tailwind watcher to generate style.css in the Ema's content directory, and have the FileSystem watcher automatically pick it up. In addition, 'hash' the URL of style.css based on its contents so that stale browser cache is not used. All of this can perhaps be abstracted out in some way and have Ema expose it via a simpler API - but for now, check this PR to see how to do this in your own Ema site.

srid commented 2 years ago

There is a very simple solution here. All we need to do is run the tailwind CLI once at the start of Ema live server, because the classes are used in Html DSL in Haskell anyway:

https://github.com/srid/banyan/blob/e9119e2c055c00a720a17cab10c0a7811cd85765/src/Main.hs#L29-L40

For other use cases (like Emanote) that use plain .html files (or specify classes in other ways) - we will have to run tailwind in JIT mode using the -w flag, which means we would have to run it as a parallel process. But that can be explored in Emanote side.

For Ema.Helpers.Tailwind I suppose it is sufficient to expose a buildCss :: (MonadIO m, MonadLogger m) => Ema.CLI.Action -> m () function that users can call inside runEma.

This does mean that tailwindcss becomes a build time dependency of Ema (if with-helpers flag is set in cabal), which is normally taken care of automatically when using Nix. But cabal/stack users have to manually install tailwindcli.

EDIT: Actually we do have to run tailwind in JIT mode, otherwise the one-off run can take as long as 1 second (perceptible delay). So we gotta figure process runner to run tailwind in parallel and integrate the generated CSS to our routes.

srid commented 2 years ago

https://github.com/srid/ema-template now runs Tailwind 3.x, both in live server and static site generation.

This issue is done to the level of alpha quality, and is usable today. But I'll keep it open for any potential improvements (especially for Heist templating in Emanote) and improving docs.

srid commented 8 months ago

https://github.com/srid/emanote/pull/503 demonstrates using Tailwind CDN to get 3.x in live server.