dbern

dbern

Adding `--tailwind` flag to phx.new

I heard on a podcast episode on Thinking |> Elixir that there could be some TailwindCSS support when generating new Phoenix projects.

https://twitter.com/j_tormey/status/1334168111675809792

I’d love to work on this feature, but before I start slinging code, I’d like some buy-in from the Phoenix team. Are there any thoughts on how Tailwind could be included in a new Phoenix project?


Should this be the default for new Phoenix projects, instead of the included Milligram CSS? I like how Milligram is super easy as a drop-in without really any work to pull it out if you wanted to use a different CSS framework. Literally delete the phoenix.css file and you’re done.


Should this be opt-in via a --tailwind flag on the phx.new generator? I’m inclined to go this way, since including Tailwind also has some workflow changes, and several files. Adam Wathan seems to suggest avoiding using Sass when also using PostCSS to avoid some glitches; so I’m also thinking that this --tailwind flag would also not include sass by default and instead setup Sass-like features through PostCSS

  • postcss-import
  • postcss-nested

other thoughts? Also heads up, there’s an in-progress guide for integrating TailwindCSS into Phoenix from the tailwindcss.com site

First Post!

thojanssens1

thojanssens1

I hate Tailwind. It’s overrated. Company I worked for used LiveView and Tailwind for their CSS. They end up with all these small classes in their html templates which leads to a huge copy paste mess. Tailwind doesn’t encourage them to create reusable classes for cross-view components.
Then you have to learn a whole new language, the mapping between Tailwind classes and the actual css. E.g. items-center <> align-items: center. I had then constantly a tab open to find those mappings.
It is also polluting the templates with a huge amount of CSS specific details. Templates become unreadable.
For the next job, I’ll have to ask the company if they use Tailwind…

Most Liked

josevalim

josevalim

Creator of Elixir

As the person who literally implemented the Rails Application Templates in the incarnation still used today, they have many pitfalls that may not be obvious unless you maintain them and/or write anything mildly complex with them. For example:

  1. Brittle. Whenever you change the generated code, which is often common, there is a chance template code will break or it will generate the wrong application

  2. They don’t compose. As application templates get more and more complex, it is unlikely you can run multiple of them

  3. Untested. Back then I don’t remember seeing a single application generator which comes with a comprehensive test suite (which would help addressing previous points)

  4. Hard to maintain. It is really hard to maintain an application template as you extend it because they lack structure

But most importantly, I think application templates most often miss the point: what are the odds that you need to execute something exactly when the application is being generated? For example, take mix phx.gen.auth, it could be designed as an --auth flag to phx.new but it is just so much better as its own standalone project.

So what about Tailwind support on Phoenix if it is not part of Phoenix? How would someone approach that? Easy:

$ mix archive.install hex phx_new
$ mix archive.install hex phx_new_tailwind
$ mix phx.new foo
$ cd foo
$ mix phx.new.tailwind # change everything required for tailwind support

While this approach doesn’t necessarily address point 1, because this type of code will always be brittle, it pretty much does better in all other points mentioned above. The beauty of phx_new_tailwind is:

  1. Is its own project, with proper structure, and hopefully tests

  2. Has its own command, which means it has a proper place to document all of its options and behaviour (something you don’t get with application templates iirc)

I am sure this process is nowhere as fleshed out as Rails Application Templates, but I would rather use this approach as a starting point and improve it based on feedback than pick a solution that has many known pitfalls. In any case, it is 100% possible today.

This is not even specific to Phoenix… as the same can be achieved with Rails generators and it is pretty much the approach I preferred back then: devise and simple_form used rails devise:install and rails simple_form:install commands instead of templates. I remember maintaining some front-end based installers way back then too.

sasajuric

sasajuric

Author of Elixir In Action

I used to think that too until I started consulting an agency, and what I saw made me change my minds. My clients start new projects fairly frequently. They want to keep the different projects technically as similar as possible to each other (language, frameworks, libraries, CI/CD). When I started working with them they have already built their own custom generator which expanded on phx.new generating some custom stuff (like e.g. deploy pipeline).

One of my main tasks has been introducing common Elixir style & practices to their projects, with the purpose of assisting with project switches. A company-wide custom generator has been indispensable in making this happen, so I’ve spent significant amount of time expanding it. Examples of simpler things we’re doing include generating our own custom credo configuration, or setting up default CI checks (formatter, credo, dialyzer, migrations reversibility, OTP release).

In addition, the generator also performs some more complicated changes on top of phx.new, such as moving db/endpoint configuration to init callbacks, renaming some files, most notably everything under the web folder, together with renaming corresponding modules. Changing some configurations in config scripts, etc. Such changes are made using a hacky combination of regex search & replaces, file operations (e.g. rename), or in some cases by completely overwriting the generated files.

It all feels fragile, and I sometimes wonder if we should completely part ways with phx.new and generate everything ourselves. However, the main challenge is that it’s unclear what exactly should be done to add different layers of Phoenix to the existing non-Phoenix project. Last time I was doing that, I invoked mix phx.new my_existing_project in /tmp, then copied that over the existing project, and carefully analyzed git differences, which was far from perfect. Moreover, once such generator is built, I fear that upgrading it to the next Phoenix is going to be much harder.

A comprehensive step-by-step guide explaining how to add Phoenix to existing project to existing project might be of great help here. I’d expect such guide to cover various scenarios, starting with the basic API, and then expanding with HTML, LiveView, and webpack, and of course including recipes for std configuration (e.g. dev-only live reload, debug errors, etc.). Understanding the changes between two Phoenix version could then amount to diffing the guides, which should be easier to comprehend than diff of the generator project.

Other than that, I’m not really sure what kind of support could be offered by the core generators to simplify the kind of changes we’re doing.

tcoopman

tcoopman

I actually love tailwind and I appreciate your opinion on tailwind, but I don’t see how your comment adds any value to the question above.

To the question, I don’t think tailwind should be the default. I would like it, but I think it’s too opinionated to be a default.
As an extra option, I’m not sure either, it’s an extra option to support.

Would it be possible to extend the mix task as a separate package so that the support burden doesn’t fall on the Phoenix team?

11
Post #2

Last Post!

niccolox

niccolox

feels more and more like a phx generator contrib pattern requirement

Where Next?

Popular in Discussions Top

rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
MarioFlach
Hello, I want to share a project I’ve been working on for a while: https://github.com/almightycouch/gitgud Background Some time ago I ...
New
acrolink
How does the two languages compare when it comes to server side application development? Any experiences or ideas? Thank you.
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
wmnnd
The Go vs Elixir thread got me thinking: Would it be too hard to implement a simple mechanism for creating Go-style static app binaries f...
New
AstonJ
If so I (and hopefully others!) might have some tips for you :slight_smile: But first, please say which area you’re finding most challen...
New
cvkmohan
The upcoming Phoenix 1.6 release looks very interesting. Became a habit to watch the commits - and - what they are bringing in. phx.gen...
New

Other popular topics Top

stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31586 112
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40165 209
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42716 114
New

We're in Beta

About us Mission Statement