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
Most Liked
josevalim
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:
-
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
-
They don’t compose. As application templates get more and more complex, it is unlikely you can run multiple of them
-
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)
-
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:
-
Is its own project, with proper structure, and hopefully tests
-
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
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
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?
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








