I used to work with create-elm-app but for the past year or so I've been using a simpler set-up. Instead of rewriting that set-up all the time, I decided to make it a template and here it is. This set-up aims to be simple yet fully working for writing elm applications styled with tailwindcss and packed up with parcel.js.
You can see the result here
Once you've created your new project with this template just cd
in it and run:
npm install
Once you've all the dependencies installed, you just need to run npm start
which uses run-pty
to run several
commands side by side. In our case, it will run the script to generate the CSS
via the tailwind CLI and pack everything up in a nice development server with parcel.
It will also start an elm-doc-preview
so you don't need to hit the package.elm-lang.com to
read the doc of any elm package you've installed on your machine, ain't it cool?
As a bonus, npm start
will also run elm-review
every time your code change.
That should be all!
The build step is quite simple in truth. Firstly, the
tailwind-cli is responsible for generating a single
css file from the tailwind.config.js
file and the src/css/style.css
file as well as any CSS file you'd refer too from that entry point.
The single CSS file is generated at src/style.css
(this will change one day
and be placed somewhere else than in src
).
This css build step can be run either by npm run css:build
, which will run
once, or by running npm run css:watch
which will run the build each time the
tailwind.config.js
file is changed or one of the CSS file inside src/css/
does.
Lastly, npm run css:prod
will activate tailwind's purging and remove from the
generated CSS any tailwind rule that is not used.
NOTE: with tailwindcss v3 and the Just-in-time mode, I had to add the SAFELISTING
trick to preserve my work workflow.
I usually start with a rough UI that I make in elm, then I jump in the dev-tools of my browser and fine tune the classes.
The safelist
trick allows to "force" the JIT to generate all the classes so that I can keep tweaking stuff in my web-browser.
Parcel is used to pack everything else and generate the final
files. I won't say much about parcel in here since their doc is great and the
main benefit of Parcel is that it only need an entry point to workout what you
need for your build. In this template, the entry point is simply
src/index.html
. From there, Parcel detects src/index.ts
which loads the
src/elm/Main.elm
, etc.
The files generated by Parcel are all hashed to make it easier to work with updating assets:
- only the
index.html
needs to be invalidated from cache (e.g. Amazon cloudfront, ...) - the hashes won't change if the file content won't change