diff --git a/Gemfile b/Gemfile index 1487b97..38f79ad 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } # Specify your gem's dependencies in importmap-rails.gemspec. gemspec -rails_version = ENV["RAILS_VERSION"] || "6.1.0" +rails_version = ENV["RAILS_VERSION"] || "8.0.1" gem "rails", "~> #{rails_version}" gem "sqlite3" diff --git a/Gemfile.lock b/Gemfile.lock index f44fffc..7da5085 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,187 +1,259 @@ PATH remote: . specs: - cssbundling-rails (1.3.3) + cssbundling-rails (1.4.3) railties (>= 6.0.0) GEM remote: https://rubygems.org/ specs: - actioncable (6.1.3.1) - actionpack (= 6.1.3.1) - activesupport (= 6.1.3.1) + actioncable (8.0.1) + actionpack (= 8.0.1) + activesupport (= 8.0.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.3.1) - actionpack (= 6.1.3.1) - activejob (= 6.1.3.1) - activerecord (= 6.1.3.1) - activestorage (= 6.1.3.1) - activesupport (= 6.1.3.1) - mail (>= 2.7.1) - actionmailer (6.1.3.1) - actionpack (= 6.1.3.1) - actionview (= 6.1.3.1) - activejob (= 6.1.3.1) - activesupport (= 6.1.3.1) - mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 2.0) - actionpack (6.1.3.1) - actionview (= 6.1.3.1) - activesupport (= 6.1.3.1) - rack (~> 2.0, >= 2.0.9) + zeitwerk (~> 2.6) + actionmailbox (8.0.1) + actionpack (= 8.0.1) + activejob (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) + mail (>= 2.8.0) + actionmailer (8.0.1) + actionpack (= 8.0.1) + actionview (= 8.0.1) + activejob (= 8.0.1) + activesupport (= 8.0.1) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (8.0.1) + actionview (= 8.0.1) + activesupport (= 8.0.1) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.3.1) - actionpack (= 6.1.3.1) - activerecord (= 6.1.3.1) - activestorage (= 6.1.3.1) - activesupport (= 6.1.3.1) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (8.0.1) + actionpack (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.3.1) - activesupport (= 6.1.3.1) + actionview (8.0.1) + activesupport (= 8.0.1) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.3.1) - activesupport (= 6.1.3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (8.0.1) + activesupport (= 8.0.1) globalid (>= 0.3.6) - activemodel (6.1.3.1) - activesupport (= 6.1.3.1) - activerecord (6.1.3.1) - activemodel (= 6.1.3.1) - activesupport (= 6.1.3.1) - activestorage (6.1.3.1) - actionpack (= 6.1.3.1) - activejob (= 6.1.3.1) - activerecord (= 6.1.3.1) - activesupport (= 6.1.3.1) - marcel (~> 1.0.0) - mini_mime (~> 1.0.2) - activesupport (6.1.3.1) - concurrent-ruby (~> 1.0, >= 1.0.2) + activemodel (8.0.1) + activesupport (= 8.0.1) + activerecord (8.0.1) + activemodel (= 8.0.1) + activesupport (= 8.0.1) + timeout (>= 0.4.0) + activestorage (8.0.1) + actionpack (= 8.0.1) + activejob (= 8.0.1) + activerecord (= 8.0.1) + activesupport (= 8.0.1) + marcel (~> 1.0) + activesupport (8.0.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - tzinfo (~> 2.0) - zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - builder (3.2.4) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + base64 (0.2.0) + benchmark (0.4.0) + bigdecimal (3.1.9) + builder (3.3.0) byebug (11.1.3) - capybara (3.35.3) + capybara (3.40.0) addressable + matrix mini_mime (>= 0.1.3) - nokogiri (~> 1.8) + nokogiri (~> 1.11) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - childprocess (3.0.0) - concurrent-ruby (1.1.9) + concurrent-ruby (1.3.5) + connection_pool (2.5.0) crass (1.0.6) - erubi (1.10.0) - globalid (0.5.1) - activesupport (>= 5.0) - i18n (1.8.10) + date (3.4.1) + drb (2.2.1) + erubi (1.13.1) + globalid (1.2.1) + activesupport (>= 6.1) + i18n (1.14.7) concurrent-ruby (~> 1.0) - loofah (2.10.0) + io-console (0.8.0) + irb (1.15.1) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + logger (1.6.6) + loofah (2.24.0) crass (~> 1.0.2) - nokogiri (>= 1.5.9) - mail (2.7.1) + nokogiri (>= 1.12.0) + mail (2.8.1) mini_mime (>= 0.1.1) - marcel (1.0.1) - method_source (1.0.0) - mini_mime (1.0.3) - minitest (5.14.4) - nio4r (2.5.7) - nokogiri (1.15.2-aarch64-linux) + net-imap + net-pop + net-smtp + marcel (1.0.4) + matrix (0.4.2) + mini_mime (1.1.5) + minitest (5.25.4) + net-imap (0.5.6) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + nio4r (2.7.4) + nokogiri (1.18.3-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.3-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.18.3-arm-linux-gnu) racc (~> 1.4) - nokogiri (1.15.2-arm64-darwin) + nokogiri (1.18.3-arm-linux-musl) racc (~> 1.4) - nokogiri (1.15.2-x86_64-darwin) + nokogiri (1.18.3-arm64-darwin) racc (~> 1.4) - nokogiri (1.15.2-x86_64-linux) + nokogiri (1.18.3-x86_64-darwin) racc (~> 1.4) - public_suffix (4.0.6) - racc (1.7.1) - rack (2.2.3) - rack-test (1.1.0) - rack (>= 1.0, < 3) - rails (6.1.3.1) - actioncable (= 6.1.3.1) - actionmailbox (= 6.1.3.1) - actionmailer (= 6.1.3.1) - actionpack (= 6.1.3.1) - actiontext (= 6.1.3.1) - actionview (= 6.1.3.1) - activejob (= 6.1.3.1) - activemodel (= 6.1.3.1) - activerecord (= 6.1.3.1) - activestorage (= 6.1.3.1) - activesupport (= 6.1.3.1) + nokogiri (1.18.3-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.3-x86_64-linux-musl) + racc (~> 1.4) + pp (0.6.2) + prettyprint + prettyprint (0.2.0) + psych (5.2.3) + date + stringio + public_suffix (6.0.1) + racc (1.8.1) + rack (3.1.10) + rack-session (2.1.0) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (8.0.1) + actioncable (= 8.0.1) + actionmailbox (= 8.0.1) + actionmailer (= 8.0.1) + actionpack (= 8.0.1) + actiontext (= 8.0.1) + actionview (= 8.0.1) + activejob (= 8.0.1) + activemodel (= 8.0.1) + activerecord (= 8.0.1) + activestorage (= 8.0.1) + activesupport (= 8.0.1) bundler (>= 1.15.0) - railties (= 6.1.3.1) - sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + railties (= 8.0.1) + rails-dom-testing (2.2.0) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.3.0) - loofah (~> 2.3) - railties (6.1.3.1) - actionpack (= 6.1.3.1) - activesupport (= 6.1.3.1) - method_source - rake (>= 0.8.7) - thor (~> 1.0) - rake (13.0.6) - regexp_parser (2.1.1) - rexml (3.2.5) - rubyzip (2.3.2) - selenium-webdriver (3.142.7) - childprocess (>= 0.5, < 4.0) - rubyzip (>= 1.2.2) - sprockets (4.0.2) - concurrent-ruby (~> 1.0) - rack (> 1, < 3) - sprockets-rails (3.2.2) - actionpack (>= 4.0) - activesupport (>= 4.0) - sprockets (>= 3.0.0) - sqlite3 (1.4.2) - stimulus-rails (0.3.8) - rails (>= 6.0.0) - thor (1.1.0) - turbo-rails (0.7.4) - rails (>= 6.0.0) - tzinfo (2.0.4) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (8.0.1) + actionpack (= 8.0.1) + activesupport (= 8.0.1) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rake (13.2.1) + rdoc (6.12.0) + psych (>= 4.0.0) + regexp_parser (2.10.0) + reline (0.6.0) + io-console (~> 0.5) + rexml (3.4.1) + rubyzip (2.4.1) + securerandom (0.4.1) + selenium-webdriver (4.10.0) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + sqlite3 (2.6.0-aarch64-linux-gnu) + sqlite3 (2.6.0-aarch64-linux-musl) + sqlite3 (2.6.0-arm-linux-gnu) + sqlite3 (2.6.0-arm-linux-musl) + sqlite3 (2.6.0-arm64-darwin) + sqlite3 (2.6.0-x86_64-darwin) + sqlite3 (2.6.0-x86_64-linux-gnu) + sqlite3 (2.6.0-x86_64-linux-musl) + stimulus-rails (1.3.4) + railties (>= 6.0.0) + stringio (3.1.5) + thor (1.3.2) + timeout (0.4.3) + turbo-rails (2.0.13) + actionpack (>= 7.1.0) + railties (>= 7.1.0) + tzinfo (2.0.6) concurrent-ruby (~> 1.0) - webdrivers (4.6.0) + uri (1.0.3) + useragent (0.16.11) + webdrivers (5.3.1) nokogiri (~> 1.6) rubyzip (>= 1.3.0) - selenium-webdriver (>= 3.0, < 4.0) - websocket-driver (0.7.5) + selenium-webdriver (~> 4.0, < 4.11) + websocket (1.2.11) + websocket-driver (0.7.7) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.4.2) + zeitwerk (2.7.2) PLATFORMS - aarch64-linux - arm64-darwin-20 - arm64-darwin-21 - arm64-darwin-22 - x86_64-darwin-20 - x86_64-darwin-21 - x86_64-linux + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES byebug capybara cssbundling-rails! - rails (~> 6.1.0) + rails (~> 8.0.1) rexml selenium-webdriver sqlite3 @@ -190,4 +262,4 @@ DEPENDENCIES webdrivers BUNDLED WITH - 2.2.33 + 2.6.2 diff --git a/README.md b/README.md index a6c1db4..40d04be 100644 --- a/README.md +++ b/README.md @@ -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. ## Installation @@ -22,8 +21,7 @@ You must already have node and yarn installed on your system. You will also need 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]`. - +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 @@ -31,9 +29,17 @@ Or, in Rails 7+, you can preconfigure your new application to use a specific bun 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? -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? @@ -41,7 +47,7 @@ Some CSS packages use new CSS features that are not supported by the default Sas ### 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. +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`? @@ -57,7 +63,16 @@ 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? + +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 diff --git a/cssbundling-rails.gemspec b/cssbundling-rails.gemspec index 8149990..c185989 100644 --- a/cssbundling-rails.gemspec +++ b/cssbundling-rails.gemspec @@ -12,4 +12,6 @@ Gem::Specification.new do |spec| spec.files = Dir["lib/**/*", "MIT-LICENSE", "README.md"] spec.add_dependency "railties", ">= 6.0.0" + + spec.metadata["changelog_uri"] = spec.homepage + "/releases" end diff --git a/lib/cssbundling/version.rb b/lib/cssbundling/version.rb index 5b6d7ae..7524952 100644 --- a/lib/cssbundling/version.rb +++ b/lib/cssbundling/version.rb @@ -1,3 +1,3 @@ module Cssbundling - VERSION = "1.3.3" + VERSION = "1.4.3" end diff --git a/lib/install/bootstrap/install.rb b/lib/install/bootstrap/install.rb index bfea9b0..f712775 100644 --- a/lib/install/bootstrap/install.rb +++ b/lib/install/bootstrap/install.rb @@ -1,6 +1,8 @@ require_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" @@ -19,6 +21,19 @@ 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") diff --git a/lib/install/bulma/application.bulma.scss b/lib/install/bulma/application.bulma.scss index b0bc1ad..76c177e 100644 --- a/lib/install/bulma/application.bulma.scss +++ b/lib/install/bulma/application.bulma.scss @@ -1,39 +1,42 @@ -// @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; +// $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"; +// $beige-light: #d0d1cd; +// $beige-lighter: #eff0eb; +// +// Override global Sass variables from the /utilities folder +// @use "bulma/sass/utilities" with ( +// $family-primary: '"Nunito", sans-serif', +// $grey-dark: $brown, +// $grey-light: $beige-light, +// $primary: $purple, +// $link: $pink, +// $control-border-width: 2px +// ); +// +// Override Sass variables from the /form folder +// @use "bulma/sass/form" with ( +// $input-shadow: none +// ); +// +// Import the components you need +// @forward "bulma/sass/base"; +// @forward "bulma/sass/components/card"; +// @forward "bulma/sass/components/modal"; +// @forward "bulma/sass/components/navbar"; +// @forward "bulma/sass/elements/button"; +// @forward "bulma/sass/elements/icon"; +// @forward "bulma/sass/elements/content"; +// @forward "bulma/sass/elements/notification"; +// @forward "bulma/sass/elements/progress"; +// @forward "bulma/sass/elements/tag"; +// @forward "bulma/sass/layout/footer"; +// +// Import the themes so that all CSS variables have a value +// @forward "bulma/sass/themes"; +// +// Import the Google Font +// @import url("https://fonts.googleapis.com/css?family=Nunito:400,700"); -@import 'bulma/bulma'; +@use 'bulma/bulma'; diff --git a/lib/install/bulma/install.rb b/lib/install/bulma/install.rb index c5276d0..a6de35a 100644 --- a/lib/install/bulma/install.rb +++ b/lib/install/bulma/install.rb @@ -1,6 +1,8 @@ require_relative "../helpers" self.extend Helpers +apply "#{__dir__}/../install.rb" + say "Install Bulma" copy_file "#{__dir__}/application.bulma.scss", "app/assets/stylesheets/application.bulma.scss" diff --git a/lib/install/dev b/lib/install/dev index a4e05fa..d80a02d 100755 --- a/lib/install/dev +++ b/lib/install/dev @@ -1,6 +1,6 @@ #!/usr/bin/env sh -if ! gem list foreman -i --silent; then +if gem list --no-installed --exact --silent foreman; then echo "Installing foreman..." gem install foreman fi @@ -8,4 +8,4 @@ fi # Default to port 3000 if not specified export PORT="${PORT:-3000}" -exec foreman start -f Procfile.dev "$@" +exec foreman start -f Procfile.dev --env /dev/null "$@" diff --git a/lib/install/helpers.rb b/lib/install/helpers.rb index b8837f8..cf5b612 100644 --- a/lib/install/helpers.rb +++ b/lib/install/helpers.rb @@ -9,8 +9,14 @@ 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')) + tool_exists?('bun') && (File.exist?('bun.lockb') || + File.exist?('bun.lock') || + File.exist?('yarn.lock')) end def tool_exists?(tool) @@ -21,7 +27,7 @@ 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 + package_json["scripts"][name] = script.gsub('\\"', '"') File.write("package.json", JSON.pretty_generate(package_json)) run %(bun run #{name}) if run_script else diff --git a/lib/install/install.rb b/lib/install/install.rb index b241602..4e195ce 100644 --- a/lib/install/install.rb +++ b/lib/install/install.rb @@ -20,21 +20,23 @@ 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.) +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 %( Add <%= stylesheet_link_tag "application" %> within the tag in your custom layout.) + 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 @@ -54,5 +56,5 @@ end say "Add bin/dev to start foreman" -copy_file "#{__dir__}/dev", "bin/dev" +copy_file "#{__dir__}/dev", "bin/dev", force: true chmod "bin/dev", 0755, verbose: false diff --git a/lib/install/postcss/install.rb b/lib/install/postcss/install.rb index d9eb5bd..e80280b 100644 --- a/lib/install/postcss/install.rb +++ b/lib/install/postcss/install.rb @@ -1,6 +1,8 @@ require_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" diff --git a/lib/install/sass/install.rb b/lib/install/sass/install.rb index 692d60e..b05a8e5 100644 --- a/lib/install/sass/install.rb +++ b/lib/install/sass/install.rb @@ -1,6 +1,8 @@ require_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" diff --git a/lib/install/tailwind/application.tailwind.css b/lib/install/tailwind/application.tailwind.css index b5c61c9..f1d8c73 100644 --- a/lib/install/tailwind/application.tailwind.css +++ b/lib/install/tailwind/application.tailwind.css @@ -1,3 +1 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; diff --git a/lib/install/tailwind/install.rb b/lib/install/tailwind/install.rb index 7374ff4..3b7181e 100644 --- a/lib/install/tailwind/install.rb +++ b/lib/install/tailwind/install.rb @@ -1,11 +1,12 @@ require_relative "../helpers" self.extend Helpers -say "Install Tailwind (+PostCSS w/ autoprefixer)" -copy_file "#{__dir__}/tailwind.config.js", "tailwind.config.js" +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 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" diff --git a/lib/install/tailwind/package.json b/lib/install/tailwind/package.json index 32f598a..662b0f1 100644 --- a/lib/install/tailwind/package.json +++ b/lib/install/tailwind/package.json @@ -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" } } diff --git a/lib/install/tailwind/tailwind.config.js b/lib/install/tailwind/tailwind.config.js deleted file mode 100644 index 4bca89f..0000000 --- a/lib/install/tailwind/tailwind.config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - content: [ - './app/views/**/*.html.erb', - './app/helpers/**/*.rb', - './app/assets/stylesheets/**/*.css', - './app/javascript/**/*.js' - ] -} diff --git a/lib/tasks/cssbundling/build.rake b/lib/tasks/cssbundling/build.rake index dcdd429..ddce5ab 100644 --- a/lib/tasks/cssbundling/build.rake +++ b/lib/tasks/cssbundling/build.rake @@ -1,5 +1,5 @@ namespace :css do - desc "Install JavaScript dependencies" + desc "Install CSS dependencies" task :install do command = Cssbundling::Tasks.install_command unless system(command) @@ -21,21 +21,42 @@ 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 - return "bun install" if File.exist?('bun.lockb') || (tool_exists?('bun') && !File.exist?('yarn.lock')) - return "yarn install" if File.exist?('yarn.lock') || tool_exists?('yarn') - raise "cssbundling-rails: No suitable tool found for installing JavaScript dependencies" + 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 - return "bun run build:css" if File.exist?('bun.lockb') || (tool_exists?('bun') && !File.exist?('yarn.lock')) - return "yarn build:css" if File.exist?('yarn.lock') || tool_exists?('yarn') - raise "cssbundling-rails: No suitable tool found for building CSS" + 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 diff --git a/lib/tasks/cssbundling/install.rake b/lib/tasks/cssbundling/install.rake index d093d8d..ba1df4c 100644 --- a/lib/tasks/cssbundling/install.rake +++ b/lib/tasks/cssbundling/install.rake @@ -1,32 +1,27 @@ namespace :css do namespace :install do - desc "Install shared elements for all bundlers" - task :shared do - system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../../install/install.rb", __dir__)}" - end - desc "Install Tailwind" - task tailwind: "css:install:shared" do + 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: "css:install:shared" do + 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: "css:install:shared" do + 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: "css:install:shared" do + 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: "css:install:shared" do + task :bulma do system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../../install/bulma/install.rb", __dir__)}" end end