cssbundling-rails-1.4.3/0000755000004100000410000000000014761637701015206 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/0000755000004100000410000000000014761637701015754 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/tasks/0000755000004100000410000000000014761637701017101 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/tasks/cssbundling/0000755000004100000410000000000014761637701021414 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/tasks/cssbundling/install.rake0000644000004100000410000000173614761637701023735 0ustar www-datawww-datanamespace :css do namespace :install do desc "Install Tailwind" task :tailwind do system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../../install/tailwind/install.rb", __dir__)}" end desc "Install PostCSS" task :postcss do system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../../install/postcss/install.rb", __dir__)}" end desc "Install Sass" task :sass do system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../../install/sass/install.rb", __dir__)}" end desc "Install Bootstrap" task :bootstrap do system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../../install/bootstrap/install.rb", __dir__)}" end desc "Install Bulma" task :bulma do system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../../install/bulma/install.rb", __dir__)}" end end end cssbundling-rails-1.4.3/lib/tasks/cssbundling/build.rake0000644000004100000410000000422414761637701023361 0ustar www-datawww-datanamespace :css do desc "Install CSS dependencies" task :install do command = Cssbundling::Tasks.install_command unless system(command) raise "cssbundling-rails: Command install failed, ensure #{command.split.first} is installed" end end desc "Build your CSS bundle" build_task = task :build do command = Cssbundling::Tasks.build_command unless system(command) raise "cssbundling-rails: Command build failed, ensure `#{command}` runs without errors" end end build_task.prereqs << :install unless ENV["SKIP_YARN_INSTALL"] || ENV["SKIP_BUN_INSTALL"] end module Cssbundling module Tasks extend self LOCK_FILES = { bun: %w[bun.lockb bun.lock yarn.lock], yarn: %w[yarn.lock], pnpm: %w[pnpm-lock.yaml], npm: %w[package-lock.json] } def install_command case when using_tool?(:bun) then "bun install" when using_tool?(:yarn) then "yarn install" when using_tool?(:pnpm) then "pnpm install" when using_tool?(:npm) then "npm install" else raise "cssbundling-rails: No suitable tool found for installing JavaScript dependencies" end end def build_command case when using_tool?(:bun) then "bun run build:css" when using_tool?(:yarn) then "yarn build:css" when using_tool?(:pnpm) then "pnpm build:css" when using_tool?(:npm) then "npm run build:css" else raise "cssbundling-rails: No suitable tool found for building CSS" end end private def tool_exists?(tool) system "command -v #{tool} > /dev/null" end def using_tool?(tool) tool_exists?(tool) && LOCK_FILES[tool].any? { |file| File.exist?(file) } end end end unless ENV["SKIP_CSS_BUILD"] if Rake::Task.task_defined?("assets:precompile") Rake::Task["assets:precompile"].enhance(["css:build"]) end if Rake::Task.task_defined?("test:prepare") Rake::Task["test:prepare"].enhance(["css:build"]) elsif Rake::Task.task_defined?("spec:prepare") Rake::Task["spec:prepare"].enhance(["css:build"]) elsif Rake::Task.task_defined?("db:test:prepare") Rake::Task["db:test:prepare"].enhance(["css:build"]) end end cssbundling-rails-1.4.3/lib/tasks/cssbundling/clobber.rake0000644000004100000410000000037714761637701023677 0ustar www-datawww-datanamespace :css do desc "Remove CSS builds" task :clobber do rm_rf Dir["app/assets/builds/**/[^.]*.{css,css.map}"], verbose: false end end if Rake::Task.task_defined?("assets:clobber") Rake::Task["assets:clobber"].enhance(["css:clobber"]) end cssbundling-rails-1.4.3/lib/install/0000755000004100000410000000000014761637701017422 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/install/sass/0000755000004100000410000000000014761637701020373 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/install/sass/application.sass.scss0000644000004100000410000000004314761637701024540 0ustar www-datawww-data// Entry point for your Sass build cssbundling-rails-1.4.3/lib/install/sass/install.rb0000644000004100000410000000065114761637701022370 0ustar www-datawww-datarequire_relative "../helpers" self.extend Helpers apply "#{__dir__}/../install.rb" say "Install Sass" copy_file "#{__dir__}/application.sass.scss", "app/assets/stylesheets/application.sass.scss" run "#{bundler_cmd} add sass" say "Add build:css script" add_package_json_script "build:css", "sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" cssbundling-rails-1.4.3/lib/install/helpers.rb0000644000004100000410000000241014761637701021406 0ustar www-datawww-datarequire 'json' module Helpers def bundler_cmd using_bun? ? "bun" : "yarn" end def bundler_run_cmd using_bun? ? "bun run" : "yarn" end def bundler_x_cmd using_bun? ? "bunx" : "npx" end def using_bun? tool_exists?('bun') && (File.exist?('bun.lockb') || File.exist?('bun.lock') || File.exist?('yarn.lock')) end def tool_exists?(tool) system "command -v #{tool} > /dev/null" end def add_package_json_script(name, script, run_script=true) if using_bun? package_json = JSON.parse(File.read("package.json")) package_json["scripts"] ||= {} package_json["scripts"][name] = script.gsub('\\"', '"') File.write("package.json", JSON.pretty_generate(package_json)) run %(bun run #{name}) if run_script else case `npx -v`.to_f when 7.1...8.0 say "Add #{name} script" run %(npm set-script #{name} "#{script}") run %(yarn #{name}) if run_script when (8.0..) say "Add #{name} script" run %(npm pkg set scripts.#{name}="#{script}") run %(yarn #{name}) if run_script else say %(Add "scripts": { "#{name}": "#{script}" } to your package.json), :green end end end end cssbundling-rails-1.4.3/lib/install/bootstrap/0000755000004100000410000000000014761637701021437 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/install/bootstrap/application.bootstrap.scss0000644000004100000410000000012414761637701026650 0ustar www-datawww-data@import 'bootstrap/scss/bootstrap'; @import 'bootstrap-icons/font/bootstrap-icons'; cssbundling-rails-1.4.3/lib/install/bootstrap/install.rb0000644000004100000410000000437414761637701023442 0ustar www-datawww-datarequire_relative "../helpers" self.extend Helpers apply "#{__dir__}/../install.rb" say "Install Bootstrap with Bootstrap Icons, Popperjs/core and Autoprefixer" copy_file "#{__dir__}/application.bootstrap.scss", "app/assets/stylesheets/application.bootstrap.scss" run "#{bundler_cmd} add sass bootstrap bootstrap-icons @popperjs/core postcss postcss-cli autoprefixer nodemon" inject_into_file "config/initializers/assets.rb", after: /.*Rails.application.config.assets.paths.*\n/ do <<~RUBY Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap-icons/font") RUBY end if Rails.root.join("app/javascript/application.js").exist? say "Appending Bootstrap JavaScript import to default entry point" append_to_file "app/javascript/application.js", %(import * as bootstrap from "bootstrap"\n) else say %(Add import * as bootstrap from "bootstrap" to your entry point JavaScript file), :red end if Rails.root.join("config/importmap.rb").exist? say "Pin Bootstrap" append_to_file "config/importmap.rb", %(pin "bootstrap", to: "bootstrap.bundle.min.js"\n) inject_into_file "config/initializers/assets.rb", after: /.*\/bootstrap-icons\/font.*\n/ do <<~RUBY Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap/dist/js") RUBY end append_to_file "config/initializers/assets.rb", %(Rails.application.config.assets.precompile << "bootstrap.bundle.min.js") end add_package_json_script("build:css:compile", "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules") add_package_json_script("build:css:prefix", "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css") add_package_json_script("build:css", "#{bundler_run_cmd} build:css:compile && #{bundler_run_cmd} build:css:prefix") add_package_json_script("watch:css", "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec \\\"#{bundler_run_cmd} build:css\\\"", false) gsub_file "Procfile.dev", "build:css --watch", "watch:css" package_json = JSON.parse(File.read("package.json")) package_json["browserslist"] ||= {} package_json["browserslist"] = ["defaults"] File.write("package.json", JSON.pretty_generate(package_json)) cssbundling-rails-1.4.3/lib/install/Procfile_for_node.dev0000644000004100000410000000011314761637701023533 0ustar www-datawww-dataweb: env RUBY_DEBUG_OPEN=true bin/rails server css: yarn build:css --watch cssbundling-rails-1.4.3/lib/install/postcss/0000755000004100000410000000000014761637701021120 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/install/postcss/postcss.config.js0000644000004100000410000000020314761637701024413 0ustar www-datawww-datamodule.exports = { plugins: [ require('postcss-import'), require('postcss-nesting'), require('autoprefixer'), ], } cssbundling-rails-1.4.3/lib/install/postcss/application.postcss.css0000644000004100000410000000005114761637701025626 0ustar www-datawww-data/* Entry point for your PostCSS build */ cssbundling-rails-1.4.3/lib/install/postcss/install.rb0000644000004100000410000000104414761637701023112 0ustar www-datawww-datarequire_relative "../helpers" self.extend Helpers apply "#{__dir__}/../install.rb" say "Install PostCSS w/ nesting and autoprefixer" copy_file "#{__dir__}/postcss.config.js", "postcss.config.js" copy_file "#{__dir__}/application.postcss.css", "app/assets/stylesheets/application.postcss.css" run "#{bundler_cmd} add postcss postcss-cli postcss-import postcss-nesting autoprefixer" say "Add build:css script" add_package_json_script "build:css", "postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css" cssbundling-rails-1.4.3/lib/install/bulma/0000755000004100000410000000000014761637701020522 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/install/bulma/install.rb0000644000004100000410000000066614761637701022525 0ustar www-datawww-datarequire_relative "../helpers" self.extend Helpers apply "#{__dir__}/../install.rb" say "Install Bulma" copy_file "#{__dir__}/application.bulma.scss", "app/assets/stylesheets/application.bulma.scss" run "#{bundler_cmd} add sass bulma" say "Add build:css script" add_package_json_script "build:css", "sass ./app/assets/stylesheets/application.bulma.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" cssbundling-rails-1.4.3/lib/install/bulma/application.bulma.scss0000644000004100000410000000216214761637701025022 0ustar www-datawww-data// @charset "utf-8"; // Import a Google Font // @import url('https://fonts.googleapis.com/css?family=Nunito:400,700'); // Set your brand colors // $purple: #8A4D76; // $pink: #FA7C91; // $brown: #757763; // $beige-light: #D0D1CD; // $beige-lighter: #EFF0EB; // Update Bulma's global variables // $family-sans-serif: "Nunito", sans-serif; // $grey-dark: $brown; // $grey-light: $beige-light; // $primary: $purple; // $link: $pink; // $widescreen-enabled: false; // $fullhd-enabled: false; // Update some of Bulma's component variables // $body-background-color: $beige-lighter; // $control-border-width: 2px; // $input-border-color: transparent; // $input-shadow: none; // Import only what you need from Bulma // @import "bulma/sass/utilities/_all.sass"; // @import "bulma/sass/base/_all.sass"; // @import "bulma/sass/elements/button.sass"; // @import "bulma/sass/elements/container.sass"; // @import "bulma/sass/elements/title.sass"; // @import "bulma/sass/form/_all.sass"; // @import "bulma/sass/components/navbar.sass"; // @import "bulma/sass/layout/hero.sass"; // @import "bulma/sass/layout/section.sass"; @import 'bulma/bulma'; cssbundling-rails-1.4.3/lib/install/install.rb0000644000004100000410000000417214761637701021421 0ustar www-datawww-datarequire_relative "helpers" self.extend Helpers say "Build into app/assets/builds" empty_directory "app/assets/builds" keep_file "app/assets/builds" if (sprockets_manifest_path = Rails.root.join("app/assets/config/manifest.js")).exist? append_to_file sprockets_manifest_path, %(//= link_tree ../builds\n) say "Stop linking stylesheets automatically" gsub_file "app/assets/config/manifest.js", "//= link_directory ../stylesheets .css\n", "" end if Rails.root.join(".gitignore").exist? append_to_file(".gitignore", %(\n/app/assets/builds/*\n!/app/assets/builds/.keep\n)) append_to_file(".gitignore", %(\n/node_modules\n)) end say "Remove app/assets/stylesheets/application.css so build output can take over" remove_file "app/assets/stylesheets/application.css" if Rails::VERSION::MAJOR < 8 if (app_layout_path = Rails.root.join("app/views/layouts/application.html.erb")).exist? say "Add stylesheet link tag in application layout" insert_into_file( app_layout_path.to_s, defined?(Turbo) ? %(\n <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>) : %(\n <%= stylesheet_link_tag "application" %>), before: /\s*<\/head>/ ) else say "Default application.html.erb is missing!", :red if defined?(Turbo) say %( Add <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> within the tag in your custom layout.) else say %( Add <%= stylesheet_link_tag "application" %> within the tag in your custom layout.) end end end unless Rails.root.join("package.json").exist? say "Add default package.json" copy_file "#{__dir__}/package.json", "package.json" end if Rails.root.join("Procfile.dev").exist? append_to_file "Procfile.dev", "css: #{bundler_run_cmd} build:css --watch\n" else say "Add default Procfile.dev" copy_file "#{__dir__}/#{using_bun? ? "Procfile_for_bun.dev" : "Procfile_for_node.dev"}", "Procfile.dev" say "Ensure foreman is installed" run "gem install foreman" end say "Add bin/dev to start foreman" copy_file "#{__dir__}/dev", "bin/dev", force: true chmod "bin/dev", 0755, verbose: false cssbundling-rails-1.4.3/lib/install/dev0000755000004100000410000000040314761637701020123 0ustar www-datawww-data#!/usr/bin/env sh if gem list --no-installed --exact --silent foreman; then echo "Installing foreman..." gem install foreman fi # Default to port 3000 if not specified export PORT="${PORT:-3000}" exec foreman start -f Procfile.dev --env /dev/null "$@" cssbundling-rails-1.4.3/lib/install/tailwind/0000755000004100000410000000000014761637701021235 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/install/tailwind/application.tailwind.css0000644000004100000410000000002714761637701026063 0ustar www-datawww-data@import "tailwindcss"; cssbundling-rails-1.4.3/lib/install/tailwind/install.rb0000644000004100000410000000073714761637701023237 0ustar www-datawww-datarequire_relative "../helpers" self.extend Helpers apply "#{__dir__}/../install.rb" say "Install Tailwind" copy_file "#{__dir__}/application.tailwind.css", "app/assets/stylesheets/application.tailwind.css" run "#{bundler_cmd} add tailwindcss@latest @tailwindcss/cli@latest" say "Add build:css script" add_package_json_script "build:css", "#{bundler_x_cmd} @tailwindcss/cli -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify" cssbundling-rails-1.4.3/lib/install/tailwind/package.json0000644000004100000410000000030114761637701023515 0ustar www-datawww-data{ "name": "app", "private": "true", "scripts": { "build:css": "npx @tailwindcss/cli -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css" } } cssbundling-rails-1.4.3/lib/install/Procfile_for_bun.dev0000644000004100000410000000011614761637701023375 0ustar www-datawww-dataweb: env RUBY_DEBUG_OPEN=true bin/rails server css: bun run build:css --watch cssbundling-rails-1.4.3/lib/install/package.json0000644000004100000410000000005114761637701021704 0ustar www-datawww-data{ "name": "app", "private": "true" } cssbundling-rails-1.4.3/lib/cssbundling/0000755000004100000410000000000014761637701020267 5ustar www-datawww-datacssbundling-rails-1.4.3/lib/cssbundling/engine.rb0000755000004100000410000000007614761637701022067 0ustar www-datawww-datamodule Cssbundling class Engine < ::Rails::Engine end end cssbundling-rails-1.4.3/lib/cssbundling/version.rb0000644000004100000410000000005314761637701022277 0ustar www-datawww-datamodule Cssbundling VERSION = "1.4.3" end cssbundling-rails-1.4.3/lib/cssbundling-rails.rb0000644000004100000410000000012314761637701021720 0ustar www-datawww-datamodule Cssbundling end require "cssbundling/version" require "cssbundling/engine" cssbundling-rails-1.4.3/MIT-LICENSE0000644000004100000410000000205414761637701016643 0ustar www-datawww-dataCopyright (c) 2021 David Heinemeier Hansson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cssbundling-rails-1.4.3/cssbundling-rails.gemspec0000644000004100000410000000443414761637701022203 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: cssbundling-rails 1.4.3 ruby lib Gem::Specification.new do |s| s.name = "cssbundling-rails".freeze s.version = "1.4.3" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.metadata = { "changelog_uri" => "https://github.com/rails/cssbundling-rails/releases" } if s.respond_to? :metadata= s.require_paths = ["lib".freeze] s.authors = ["David Heinemeier Hansson".freeze, "Dom Christie".freeze] s.date = "2025-03-03" s.email = "david@loudthinking.com".freeze s.files = ["MIT-LICENSE".freeze, "README.md".freeze, "lib/cssbundling-rails.rb".freeze, "lib/cssbundling/engine.rb".freeze, "lib/cssbundling/version.rb".freeze, "lib/install/Procfile_for_bun.dev".freeze, "lib/install/Procfile_for_node.dev".freeze, "lib/install/bootstrap/application.bootstrap.scss".freeze, "lib/install/bootstrap/install.rb".freeze, "lib/install/bulma/application.bulma.scss".freeze, "lib/install/bulma/install.rb".freeze, "lib/install/dev".freeze, "lib/install/helpers.rb".freeze, "lib/install/install.rb".freeze, "lib/install/package.json".freeze, "lib/install/postcss/application.postcss.css".freeze, "lib/install/postcss/install.rb".freeze, "lib/install/postcss/postcss.config.js".freeze, "lib/install/sass/application.sass.scss".freeze, "lib/install/sass/install.rb".freeze, "lib/install/tailwind/application.tailwind.css".freeze, "lib/install/tailwind/install.rb".freeze, "lib/install/tailwind/package.json".freeze, "lib/tasks/cssbundling/build.rake".freeze, "lib/tasks/cssbundling/clobber.rake".freeze, "lib/tasks/cssbundling/install.rake".freeze] s.homepage = "https://github.com/rails/cssbundling-rails".freeze s.licenses = ["MIT".freeze] s.rubygems_version = "3.3.15".freeze s.summary = "Bundle and process CSS with Tailwind, Bootstrap, PostCSS, Sass in Rails via Node.js.".freeze if s.respond_to? :specification_version then s.specification_version = 4 end if s.respond_to? :add_runtime_dependency then s.add_runtime_dependency(%q.freeze, [">= 6.0.0"]) else s.add_dependency(%q.freeze, [">= 6.0.0"]) end end cssbundling-rails-1.4.3/README.md0000644000004100000410000001411414761637701016466 0ustar www-datawww-data# CSS Bundling for Rails Use [Tailwind CSS](https://tailwindcss.com), [Bootstrap](https://getbootstrap.com/), [Bulma](https://bulma.io/), [PostCSS](https://postcss.org), or [Dart Sass](https://sass-lang.com/) to bundle and process your CSS, then deliver it via the asset pipeline in Rails. This gem provides installers to get you going with the bundler of your choice in a new Rails application, and a convention to use `app/assets/builds` to hold your bundled output as artifacts that are not checked into source control (the installer adds this directory to `.gitignore` by default). You develop using this approach by running the bundler in watch mode in a terminal with `yarn build:css --watch` (and your Rails server in another, if you're not using something like [puma-dev](https://github.com/puma/puma-dev)). You can also use `./bin/dev`, which will start both the Rails server and the CSS build watcher (along with a JS build watcher, if you're also using `jsbundling-rails`). Whenever the bundler detects changes to any of the stylesheet files in your project, it'll bundle `app/assets/stylesheets/application.[bundler].css` into `app/assets/builds/application.css`. This build output takes over from the regular asset pipeline default file. So you continue to refer to the build output in your layout using the standard asset pipeline approach with `<%= stylesheet_link_tag "application" %>`. When you deploy your application to production, the `css:build` task attaches to the `assets:precompile` task to ensure that all your package dependencies from `package.json` have been installed via yarn, and then runs `yarn build:css` to process your stylesheet entrypoint, as it would in development. This output is then picked up by the asset pipeline, digested, and copied into public/assets, as any other asset pipeline file. This also happens in testing where the bundler attaches to the `test:prepare` task to ensure the stylesheets have been bundled before testing commences. If your test framework does not call the `test:prepare` Rake task, ensure that your test framework runs `css:build` to bundle stylesheets before testing commences. If your setup uses [jsbundling-rails](https://github.com/rails/jsbundling-rails) (ie, esbuild + tailwind), you will also need to run `javascript:build`. That's it! You can configure your bundler options in the `build:css` script in `package.json` or `postcss.config.js` for PostCSS. ## Installation You must already have node and yarn installed on your system. You will also need npx version 7.1.0 or later. Then: 1. Run `./bin/bundle add cssbundling-rails` 2. Run `./bin/rails css:install:[tailwind|bootstrap|bulma|postcss|sass]` Or, in Rails 7+, you can preconfigure your new application to use `cssbundling-rails` for `bootstrap`, `bulma` or `postcss` with `rails new myapp --css [bootstrap|bulma|postcss]`. ## FAQ ### How does this compare to tailwindcss-rails and dartsass-rails? If you're already relying on Node to process your JavaScript, this gem is the way to go. But if you're using [the default import map setup in Rails 7+](https://github.com/rails/importmap-rails/), you can avoid having to deal with Node at all by using the standalone versions of Tailwind CSS and Dart Sass that are available through [tailwindcss-rails](https://github.com/rails/tailwindcss-rails/) and [dartsass-rails](https://github.com/rails/dartsass-rails/). It's simpler, fewer moving parts, and still has all the functionality. In Rails 7+, you can preconfigure your new application to use `tailwindcss-rails` and `dartsass-rails` with `rails new myapp --css [tailwind|sass]`. ### How do I import relative CSS files with Tailwind? 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? Some CSS packages use new CSS features that are not supported by the default SassC rails integration that previous versions of Rails used. If you hit such an incompatibility, it'll likely be in the form of a `SassC::SyntaxError` when running `assets:precompile`. The fix is to `bundle remove sass-rails` (or `sassc-rails`, if you were using that). ### Why do I get `application.css not in asset pipeline` in production? A common issue is that your repository does not contain the output directory used by the build commands. You must have `app/assets/builds` available. Add the directory with a `.keep` file, and you'll ensure it's available in production. ### How do I avoid `ActionView::Template::Error: Error: Function rgb is missing argument $green`? This might happen if your Gemfile.lock contains the legacy `sassc-rails`, which might be need while progressively migrating your project, or which might be a transitive dependency of a gem your project depends on and over which you have no control. In this case, prevent Sprockets from bundling the CSS on top of the bundling already performed by this gem. Make sure do this for all environments, not only production, otherwise your test suite may fail. ``` # config/initializers/assets.rb Rails.application.config.assets.css_compressor = nil ``` ### Why isn't Rails using my updated css files? 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 ``` ### How do I include 3rd party stylesheets from `node_modules` in my bundle? Use an `@import` statement and path to a specific stylesheet, omitting the `node_modules/` segment and the file's extension. For example: ```scss /* Desired file is at at node_modules/select2/dist/css/select2.css */ @import "select2/dist/css/select2"; ``` ## License CSS Bundling for Rails is released under the [MIT License](https://opensource.org/licenses/MIT).