From 31621ead59f92464c3b097c06011795f767a7ec8 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Fri, 24 Jan 2025 13:12:26 -0500 Subject: [PATCH] Move application.tailwind.css to a dir ignored by propshaft This file should not be included in the stylesheet link tags served to user agents. Fixes #470 --- README.md | 40 +++++++++++++-------------- lib/install/install_tailwindcss.rb | 7 +++-- lib/install/upgrade_tailwindcss.rb | 23 ++++++++++----- lib/tailwindcss/commands.rb | 2 +- lib/tailwindcss/engine.rb | 6 ++++ test/integration/user_install_test.sh | 4 +-- test/integration/user_upgrade_test.sh | 10 ++++--- 7 files changed, 54 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 5542c70a..17315ebe 100644 --- a/README.md +++ b/README.md @@ -101,9 +101,11 @@ Then, run the `tailwindcss:upgrade` task. Among other things, this will try to r Here's what the upgrade task does: - Cleans up some things in the generated `config/tailwind.config.js`. -- Runs the upstream upgrader (note: requires `npx` to run the one-time upgrade, but highly recommended). -- Removes references to the Inter font from the application layout. - If present, moves `config/postcss.config.js` to the root directory. +- If present, moves `app/assets/stylesheets/application.tailwind.css` to `app/assets/tailwind`. +- Removes unnecessary `stylesheet_link_tag "tailwindcss"` tags from the application layout. +- Removes references to the Inter font from the application layout. +- Runs the upstream upgrader (note: requires `npx` to run the one-time upgrade, but highly recommended). Here's what that upgrade looks like on a vanilla Rails app: @@ -112,29 +114,34 @@ $ bin/rails tailwindcss:upgrade apply /path/to/tailwindcss-rails/lib/install/upgrade_tailwindcss.rb Removing references to 'defaultTheme' from /home/user/myapp/config/tailwind.config.js gsub config/tailwind.config.js + Strip Inter font CSS from application layout + gsub app/views/layouts/application.html.erb + Remove unnecessary stylesheet_link_tag from application layout + gsub app/views/layouts/application.html.erb + Moving application.tailwind.css to /home/user/myapp/app/assets/tailwind + create app/assets/tailwind/application.tailwind.css + remove app/assets/stylesheets/application.tailwind.css +10.9.0 Running the upstream Tailwind CSS upgrader run npx @tailwindcss/upgrade@next --force --config /home/user/myapp/config/tailwind.config.js from "." ≈ tailwindcss v4.0.0 │ Searching for CSS files in the current directory and its subdirectories… -│ ↳ Linked `./config/tailwind.config.js` to `./app/assets/stylesheets/application.tailwind.css` +│ ↳ Linked `./config/tailwind.config.js` to `./app/assets/tailwind/application.tailwind.css` │ Migrating JavaScript configuration files… │ ↳ The configuration file at `./config/tailwind.config.js` could not be automatically migrated to the new CSS │ configuration format, so your CSS has been updated to load your existing configuration file. │ Migrating templates… │ ↳ Migrated templates for configuration file: `./config/tailwind.config.js` │ Migrating stylesheets… -│ ↳ Migrated stylesheet: `./app/assets/stylesheets/application.tailwind.css` +│ ↳ Migrated stylesheet: `./app/assets/tailwind/application.tailwind.css` │ ↳ No PostCSS config found, skipping migration. │ Updating dependencies… │ Could not detect a package manager. Please manually update `tailwindcss` to v4. │ Verify the changes and commit them to your repository. - Strip Inter font CSS from application layout - gsub app/views/layouts/application.html.erb Compile initial Tailwind build run rails tailwindcss:build from "." ≈ tailwindcss v4.0.0 - -Done in 52ms +Done in 56ms run bundle install --quiet ``` @@ -157,9 +164,11 @@ We'll try to improve the upgrade process over time, but for now you may need to ### Configuration and commands -#### Input file: `app/assets/stylesheets/application.tailwind.css` +#### Input file: `app/assets/tailwind/application.tailwind.css` + +The `tailwindcss:install` task will generate a Tailwind input file in `app/assets/tailwind/application.tailwind.css`. This is where you import the plugins you want to use and where you can setup your custom `@apply` rules. -The installer will generate a Tailwind input file in `app/assets/stylesheets/application.tailwind.css`. This is where you import the plugins you want to use and where you can setup your custom `@apply` rules. +⚠ The location of this file changed in v4, from `app/assets/stylesheets` to `app/assets/tailwind`. The `tailwindcss:upgrade` task will move it for you. #### Output file: `app/assets/builds/tailwind.css` @@ -335,17 +344,6 @@ The inline version also works:
Has the image as it's background
``` -### Conflict with pre-existing asset pipeline stylesheets - -If you get a warning `Unrecognized at-rule or error parsing at-rule ‘@tailwind’.` in the browser console after installation, you are incorrectly double-processing `application.tailwind.css`. This is a misconfiguration, even though the styles will be fully effective in many cases. - -The file `application.tailwind.css` is installed when running `rails tailwindcss:install` and is placed alongside the common `application.css` in `app/assets/stylesheets`. Because the `application.css` in a newly generated Rails app includes a `require_tree .` directive, the asset pipeline incorrectly processes `application.tailwind.css`, where it should be taken care of by `tailwindcss`. The asset pipeline ignores TailwindCSS's at-directives, and the browser can't process them. - -To fix the warning, you can either remove the `application.css`, if you don't plan to use the asset pipeline for stylesheets, and instead rely on TailwindCSS completely for styles. This is what this installer assumes. - -Or, if you do want to keep using the asset pipeline in parallel, make sure to remove the `require_tree .` line from the `application.css`. - - ## License Tailwind for Rails is released under the [MIT License](https://opensource.org/licenses/MIT). diff --git a/lib/install/install_tailwindcss.rb b/lib/install/install_tailwindcss.rb index 8957bc0e..e210d60b 100644 --- a/lib/install/install_tailwindcss.rb +++ b/lib/install/install_tailwindcss.rb @@ -1,5 +1,6 @@ APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb") CENTERING_CONTAINER_INSERTION_POINT = /^\s*<%= yield %>/.freeze +TAILWIND_ASSET_PATH = Rails.root.join("app/assets/tailwind") if APPLICATION_LAYOUT_PATH.exist? unless File.read(APPLICATION_LAYOUT_PATH).match?(/stylesheet_link_tag :app/) @@ -31,9 +32,9 @@ append_to_file(".gitignore", %(\n/app/assets/builds/*\n!/app/assets/builds/.keep\n)) end -unless Rails.root.join("app/assets/stylesheets/application.tailwind.css").exist? - say "Add default app/assets/stylesheets/application.tailwind.css" - copy_file "#{__dir__}/application.tailwind.css", "app/assets/stylesheets/application.tailwind.css" +unless TAILWIND_ASSET_PATH.join("application.tailwind.css").exist? + say "Add default #{TAILWIND_ASSET_PATH}/application.tailwind.css" + copy_file "#{__dir__}/application.tailwind.css", TAILWIND_ASSET_PATH.join("application.tailwind.css") end if Rails.root.join("Procfile.dev").exist? diff --git a/lib/install/upgrade_tailwindcss.rb b/lib/install/upgrade_tailwindcss.rb index 631e05bc..84a1aa8c 100644 --- a/lib/install/upgrade_tailwindcss.rb +++ b/lib/install/upgrade_tailwindcss.rb @@ -1,6 +1,8 @@ TAILWIND_CONFIG_PATH = Rails.root.join("config/tailwind.config.js") APPLICATION_LAYOUT_PATH = Rails.root.join("app/views/layouts/application.html.erb") POSTCSS_CONFIG_PATH = Rails.root.join("config/postcss.config.js") +OLD_TAILWIND_ASSET_PATH = Rails.root.join("app/assets/stylesheets") +TAILWIND_ASSET_PATH = Rails.root.join("app/assets/tailwind") unless TAILWIND_CONFIG_PATH.exist? say "Default tailwind.config.js is missing!", :red @@ -14,27 +16,34 @@ if POSTCSS_CONFIG_PATH.exist? say "Moving PostCSS configuration to application root directory" - FileUtils.mv(POSTCSS_CONFIG_PATH, Rails.root, verbose: true) || abort + copy_file POSTCSS_CONFIG_PATH, Rails.root.join("postcss.config.js") + remove_file POSTCSS_CONFIG_PATH end if APPLICATION_LAYOUT_PATH.exist? - if File.read(APPLICATION_LAYOUT_PATH).match?(/stylesheet_link_tag :app/) && - File.read(APPLICATION_LAYOUT_PATH).match?(/stylesheet_link_tag "tailwind"/) - say "Remove unnecessary stylesheet_link_tag from application layout" - gsub_file APPLICATION_LAYOUT_PATH.to_s, %r{^\s*<%= stylesheet_link_tag "tailwind".*%>$}, "" - end - if File.read(APPLICATION_LAYOUT_PATH).match?(/"inter-font"/) say "Strip Inter font CSS from application layout" gsub_file APPLICATION_LAYOUT_PATH.to_s, %r{, "inter-font"}, "" else say "Inter font CSS not detected.", :green end + + if File.read(APPLICATION_LAYOUT_PATH).match?(/stylesheet_link_tag :app/) && + File.read(APPLICATION_LAYOUT_PATH).match?(/stylesheet_link_tag "tailwind"/) + say "Remove unnecessary stylesheet_link_tag from application layout" + gsub_file APPLICATION_LAYOUT_PATH.to_s, %r{^\s*<%= stylesheet_link_tag "tailwind".*%>$}, "" + end else say "Default application.html.erb is missing!", :red say %( Please check your layouts and remove any "inter-font" stylesheet links.) end +if OLD_TAILWIND_ASSET_PATH.join("application.tailwind.css").exist? + say "Moving application.tailwind.css to #{TAILWIND_ASSET_PATH}" + copy_file OLD_TAILWIND_ASSET_PATH.join("application.tailwind.css"), TAILWIND_ASSET_PATH.join("application.tailwind.css") + remove_file OLD_TAILWIND_ASSET_PATH.join("application.tailwind.css") +end + if system("npx --version") say "Running the upstream Tailwind CSS upgrader" command = Shellwords.join(["npx", "@tailwindcss/upgrade@next", "--force", "--config", TAILWIND_CONFIG_PATH.to_s]) diff --git a/lib/tailwindcss/commands.rb b/lib/tailwindcss/commands.rb index ce08bb38..11105dbc 100644 --- a/lib/tailwindcss/commands.rb +++ b/lib/tailwindcss/commands.rb @@ -8,7 +8,7 @@ def compile_command(debug: false, **kwargs) command = [ Tailwindcss::Ruby.executable(**kwargs), - "-i", rails_root.join("app/assets/stylesheets/application.tailwind.css").to_s, + "-i", rails_root.join("app/assets/tailwind/application.tailwind.css").to_s, "-o", rails_root.join("app/assets/builds/tailwind.css").to_s, ] diff --git a/lib/tailwindcss/engine.rb b/lib/tailwindcss/engine.rb index 080416c4..0c020bbc 100644 --- a/lib/tailwindcss/engine.rb +++ b/lib/tailwindcss/engine.rb @@ -6,6 +6,12 @@ class Engine < ::Rails::Engine Rails.application.config.generators.stylesheets = false end + initializer "tailwindcss.exclude_asset_path", after: "propshaft.append_assets_path" do + if Rails.application.config.assets.excluded_paths # the app may not be using Propshaft + Rails.application.config.assets.excluded_paths << Rails.root.join("app/assets/tailwind") + end + end + config.app_generators do |g| g.template_engine :tailwindcss end diff --git a/test/integration/user_install_test.sh b/test/integration/user_install_test.sh index d670a106..aaf00a67 100755 --- a/test/integration/user_install_test.sh +++ b/test/integration/user_install_test.sh @@ -37,7 +37,7 @@ bin/rails tailwindcss:install # TEST: tailwind was installed correctly grep -q "
> Rakefile @@ -46,7 +46,7 @@ task :still_here do end EOF -cat >> app/assets/stylesheets/application.tailwind.css <> app/assets/tailwind/application.tailwind.css <