Skip to content

Update for Tailwind CSS v4 #164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ This also happens in testing where the bundler attaches to the `test:prepare` ta

That's it!

You can configure your bundler options in the `build:css` script in `package.json` or via the installer-generated `tailwind.config.js` for Tailwind or `postcss.config.js` for PostCSS.

You can configure your bundler options in the `build:css` script in `package.json` or `postcss.config.js` for PostCSS.
Copy link

@trinitytakei trinitytakei Feb 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there even a postcss.config.js now? In my understanding, it was dropped in v4 (as a separate package) and merged into tailwind itself?

Copy link
Contributor Author

@justalever justalever Feb 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you can install postcss independently with cssbundling-rails (bin/rails css:install:postcss)


## Installation

Expand All @@ -34,7 +33,13 @@ In Rails 7+, you can preconfigure your new application to use `tailwindcss-rails

### How do I import relative CSS files with Tailwind?

If you want to use `@import` statements as part of your Tailwind application.js file, you need to [configure Tailwind to use `postcss` and then `postcss-import`](https://tailwindcss.com/docs/using-with-preprocessors#build-time-imports). But you should also consider simply referring to your other CSS files directly, instead of bundling them all into one big file. It's better for caching, and it's simpler to setup. You can refer to other CSS files by expanding the `stylesheet_link_tag` in `application.html.erb` like so: `<%= stylesheet_link_tag "application", "other", "styles", "data-turbo-track": "reload" %>`.
Tailwind CSS 4 is configured using native CSS. Instead of bundling all your CSS into a single file, consider referencing individual CSS files directly. This approach simplifies setup and improves caching performance. To reference multiple CSS files in Rails, update the stylesheet_link_tag in application.html.erb like this:

```erb
<%= stylesheet_link_tag "application", "other", "styles", "data-turbo-track": "reload" %>
```

This ensures your files are properly linked and ready to use.

### How do I avoid SassC::SyntaxError exceptions on existing projects?

Expand All @@ -58,7 +63,7 @@ Rails.application.config.assets.css_compressor = nil
Watch out - if you precompile your files locally, those will be served over the dynamically created ones you expect. The solution:

```shell
rails assets:clobber
rails assets:clobber
```

### How do I include 3rd party stylesheets from `node_modules` in my bundle?
Expand Down
4 changes: 4 additions & 0 deletions lib/install/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ def bundler_run_cmd
using_bun? ? "bun run" : "yarn"
end

def bundler_x_cmd
using_bun? ? "bunx" : "npx"
end

def using_bun?
File.exist?('bun.lockb') || (tool_exists?('bun') && !File.exist?('yarn.lock'))
end
Expand Down
4 changes: 1 addition & 3 deletions lib/install/tailwind/application.tailwind.css
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be useful to open a separate PR just for this change, in case #164 takes a while to get merged.

This would be useful right away, regardless of how you install tailwind. Those installation woes can be worked around in various ways, but this one can't be - you just have to replace it every time, all the time.

The only question is: do we want to be backward compatible with 3.x? I don't think so (since all the generators I'm aware of are using tailwindcss@latest, which is 4.x now)

However, if backward compatibility is not a concern, I don't see why this couldn't be accepted right away as a separate PR.

7 changes: 3 additions & 4 deletions lib/install/tailwind/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

apply "#{__dir__}/../install.rb"

say "Install Tailwind (+PostCSS w/ autoprefixer)"
copy_file "#{__dir__}/tailwind.config.js", "tailwind.config.js"
say "Install Tailwind"
copy_file "#{__dir__}/application.tailwind.css", "app/assets/stylesheets/application.tailwind.css"
run "#{bundler_cmd} add tailwindcss@latest postcss@latest autoprefixer@latest"
run "#{bundler_cmd} add tailwindcss@latest @tailwindcss/cli@latest"

say "Add build:css script"
add_package_json_script "build:css",
"tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify"
"#{bundler_x_cmd} @tailwindcss/cli -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify"
2 changes: 1 addition & 1 deletion lib/install/tailwind/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"name": "app",
"private": "true",
"scripts": {
"build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css"
"build:css": "npx @tailwindcss/cli -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really necessary to run npx if you add @tailwindcss/cli as a depedency?
Also, would this also be a place to use bunx if using bun?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my testing, something like npx or bunx is necessary to run the new @tailwindcss/cli package. The Tailwind docs have this, so I was going off that.

To be honest, I'm not sure this package.json file is necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is necessary because cssbundling-rails and jsbundling-rails are enhancing some rake tasks like precompile:assets to call this build and build:css task present in the package.json

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@navidemad I mean the package.json file inside the lib/install/tailwind directory. I see no reference to it in rake tasks or elsewhere. I could be mistaken, of course.

Copy link

@gabrielso gabrielso Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is that by using npx directly in the script, you are assuming Node.js is installed, which is not true if you are, for instance, developing on a Dev Container with Bun instead of Node.js.

I see you added @tailwindcss/cli as a dependency... and the install process seems to generate the script using the correct command but it's not clear what this package.json file actually does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it's not clear what this package.json file actually does.

Correct, this legacy file was added prior to this pull request. I updated it to match the main one that gets copied. I'm not sure we need this file at all. I am in favor of removing it unless there are objections.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless there are objections

Objection, your honor 🧑‍⚖️😅

If you are using importmaps, then package.json is indeed not needed (and thus it's not even included in the generated code of a new 'omakase' app).

But if you are using a JS bundler (-j bun|webpack|esbuild|rollup), you need package.json. That's where yarn keeps its dependencies, and even commands referenced in Procfile.dev.

So yeah, please don't drop it.

Copy link
Contributor Author

@justalever justalever Feb 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if you are using a JS bundler (-j bun|webpack|esbuild|rollup), you need package.json. That's where yarn keeps its dependencies, and even commands referenced in Procfile.dev.

Thanks for chiming in! There's already one that gets copied at the root of the lib/install directory and is appended to via the tailwind installer task when running the installer. So I'm confused by the need for the additional package.json file inside lib/install/tailwind as referenced here.

}
}
8 changes: 0 additions & 8 deletions lib/install/tailwind/tailwind.config.js

This file was deleted.