cssbundling-rails-1.4.0/0000755000175000017500000000000014624652240017130 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/MIT-LICENSE0000644000175000017500000000205414624652240020565 0ustar weepingclownweepingclownCopyright (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.0/cssbundling-rails.gemspec0000644000175000017500000000405014624652240024117 0ustar weepingclownweepingclown######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: cssbundling-rails 1.4.0 ruby lib Gem::Specification.new do |s| s.name = "cssbundling-rails".freeze s.version = "1.4.0" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["David Heinemeier Hansson".freeze, "Dom Christie".freeze] s.date = "2024-01-21" 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/install/tailwind/tailwind.config.js".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.4.20".freeze s.summary = "Bundle and process CSS with Tailwind, Bootstrap, PostCSS, Sass in Rails via Node.js.".freeze s.specification_version = 4 s.add_runtime_dependency(%q.freeze, [">= 6.0.0"]) end cssbundling-rails-1.4.0/lib/0000755000175000017500000000000014624652240017676 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/cssbundling-rails.rb0000644000175000017500000000012314624652240023642 0ustar weepingclownweepingclownmodule Cssbundling end require "cssbundling/version" require "cssbundling/engine" cssbundling-rails-1.4.0/lib/cssbundling/0000755000175000017500000000000014624652240022211 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/cssbundling/version.rb0000644000175000017500000000005314624652240024221 0ustar weepingclownweepingclownmodule Cssbundling VERSION = "1.4.0" end cssbundling-rails-1.4.0/lib/cssbundling/engine.rb0000755000175000017500000000007614624652240024011 0ustar weepingclownweepingclownmodule Cssbundling class Engine < ::Rails::Engine end end cssbundling-rails-1.4.0/lib/tasks/0000755000175000017500000000000014624652240021023 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/tasks/cssbundling/0000755000175000017500000000000014624652240023336 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/tasks/cssbundling/install.rake0000644000175000017500000000173614624652240025657 0ustar weepingclownweepingclownnamespace :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.0/lib/tasks/cssbundling/build.rake0000644000175000017500000000426514624652240025310 0ustar weepingclownweepingclownnamespace :css do desc "Install JavaScript 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 def install_command case tool when :bun then "bun install" when :yarn then "yarn install" when :pnpm then "pnpm install" when :npm then "npm install" else raise "cssbundling-rails: No suitable tool found for installing JavaScript dependencies" end end def build_command case tool when :bun then "bun run build:css" when :yarn then "yarn build:css" when :pnpm then "pnpm build:css" when :npm then "npm run build:css" else raise "cssbundling-rails: No suitable tool found for building CSS" end end def tool case when File.exist?('bun.lockb') then :bun when File.exist?('yarn.lock') then :yarn when File.exist?('pnpm-lock.yaml') then :pnpm when File.exist?('package-lock.json') then :npm when tool_exists?('bun') then :bun when tool_exists?('yarn') then :yarn when tool_exists?('pnpm') then :pnpm when tool_exists?('npm') then :npm end end def tool_exists?(tool) system "command -v #{tool} > /dev/null" 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.0/lib/tasks/cssbundling/clobber.rake0000644000175000017500000000037714624652240025621 0ustar weepingclownweepingclownnamespace :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.0/lib/install/0000755000175000017500000000000014624652240021344 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/install/dev0000755000175000017500000000036314624652240022052 0ustar weepingclownweepingclown#!/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 "$@" cssbundling-rails-1.4.0/lib/install/bootstrap/0000755000175000017500000000000014624652240023361 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/install/bootstrap/application.bootstrap.scss0000644000175000017500000000012414624652240030572 0ustar weepingclownweepingclown@import 'bootstrap/scss/bootstrap'; @import 'bootstrap-icons/font/bootstrap-icons'; cssbundling-rails-1.4.0/lib/install/bootstrap/install.rb0000644000175000017500000000437414624652240025364 0ustar weepingclownweepingclownrequire_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.min.js"\n) 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/dist/js") RUBY end append_to_file "config/initializers/assets.rb", %(Rails.application.config.assets.precompile << "bootstrap.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.0/lib/install/Procfile_for_bun.dev0000644000175000017500000000011614624652240025317 0ustar weepingclownweepingclownweb: env RUBY_DEBUG_OPEN=true bin/rails server css: bun run build:css --watch cssbundling-rails-1.4.0/lib/install/Procfile_for_node.dev0000644000175000017500000000011314624652240025455 0ustar weepingclownweepingclownweb: env RUBY_DEBUG_OPEN=true bin/rails server css: yarn build:css --watch cssbundling-rails-1.4.0/lib/install/helpers.rb0000644000175000017500000000216314624652240023335 0ustar weepingclownweepingclownrequire 'json' module Helpers def bundler_cmd using_bun? ? "bun" : "yarn" end def bundler_run_cmd using_bun? ? "bun run" : "yarn" end def using_bun? File.exist?('bun.lockb') || (tool_exists?('bun') && !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.0/lib/install/postcss/0000755000175000017500000000000014624652240023042 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/install/postcss/application.postcss.css0000644000175000017500000000005114624652240027550 0ustar weepingclownweepingclown/* Entry point for your PostCSS build */ cssbundling-rails-1.4.0/lib/install/postcss/install.rb0000644000175000017500000000104414624652240025034 0ustar weepingclownweepingclownrequire_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.0/lib/install/postcss/postcss.config.js0000644000175000017500000000020314624652240026335 0ustar weepingclownweepingclownmodule.exports = { plugins: [ require('postcss-import'), require('postcss-nesting'), require('autoprefixer'), ], } cssbundling-rails-1.4.0/lib/install/tailwind/0000755000175000017500000000000014624652240023157 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/install/tailwind/application.tailwind.css0000644000175000017500000000007314624652240030006 0ustar weepingclownweepingclown@tailwind base; @tailwind components; @tailwind utilities; cssbundling-rails-1.4.0/lib/install/tailwind/tailwind.config.js0000644000175000017500000000025414624652240026575 0ustar weepingclownweepingclownmodule.exports = { content: [ './app/views/**/*.html.erb', './app/helpers/**/*.rb', './app/assets/stylesheets/**/*.css', './app/javascript/**/*.js' ] } cssbundling-rails-1.4.0/lib/install/tailwind/install.rb0000644000175000017500000000105714624652240025155 0ustar weepingclownweepingclownrequire_relative "../helpers" self.extend Helpers apply "#{__dir__}/../install.rb" say "Install Tailwind (+PostCSS w/ autoprefixer)" copy_file "#{__dir__}/tailwind.config.js", "tailwind.config.js" copy_file "#{__dir__}/application.tailwind.css", "app/assets/stylesheets/application.tailwind.css" run "#{bundler_cmd} add tailwindcss@latest postcss@latest autoprefixer@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" cssbundling-rails-1.4.0/lib/install/tailwind/package.json0000644000175000017500000000027014624652240025444 0ustar weepingclownweepingclown{ "name": "app", "private": "true", "scripts": { "build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css" } } cssbundling-rails-1.4.0/lib/install/install.rb0000644000175000017500000000405214624652240023340 0ustar weepingclownweepingclownrequire_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 (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 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" chmod "bin/dev", 0755, verbose: false cssbundling-rails-1.4.0/lib/install/package.json0000644000175000017500000000005114624652240023626 0ustar weepingclownweepingclown{ "name": "app", "private": "true" } cssbundling-rails-1.4.0/lib/install/sass/0000755000175000017500000000000014624652240022315 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/install/sass/application.sass.scss0000644000175000017500000000004314624652240026462 0ustar weepingclownweepingclown// Entry point for your Sass build cssbundling-rails-1.4.0/lib/install/sass/install.rb0000644000175000017500000000065114624652240024312 0ustar weepingclownweepingclownrequire_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.0/lib/install/bulma/0000755000175000017500000000000014624652240022444 5ustar weepingclownweepingclowncssbundling-rails-1.4.0/lib/install/bulma/application.bulma.scss0000644000175000017500000000216214624652240026744 0ustar weepingclownweepingclown// @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.0/lib/install/bulma/install.rb0000644000175000017500000000066614624652240024447 0ustar weepingclownweepingclownrequire_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.0/README.md0000644000175000017500000001414314624652240020412 0ustar weepingclownweepingclown# 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 via the installer-generated `tailwind.config.js` for Tailwind 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 a specific bundler with `rails new myapp --css [tailwind|bootstrap|bulma|postcss|sass]`. ## 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. ### 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" %>`. ### 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 `.gitkeep` 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).