Module: TsykvasRailsTemplate::Generators::BootstrapInstaller

Included in:
InstallGenerator
Defined in:
lib/generators/tsykvas_rails_template/install/bootstrap_installer.rb

Overview

Bootstrap install steps for InstallGenerator. Lives in its own module so the generator stays under the class-length limit and the Bootstrap-only logic is grouped together for opt-out (‘–skip-bootstrap`).

Expects the host to provide: ‘say_status`, `gem`, `create_file`, `empty_directory`, `append_to_file`, `in_root`, `destination_root`, `run`. All of those are Thor::Group / Rails::Generators::Base helpers.

Constant Summary collapse

BOOTSTRAP_SCSS_ENTRY_PATH =
"app/assets/stylesheets/application.bootstrap.scss"
BOOTSTRAP_SCSS_ENTRY_BODY =
<<~SCSS
  // tsykvas_rails_template — Bootstrap entrypoint compiled by dartsass-rails
  // into app/assets/builds/application.css. Override $variables above the
  // import to theme; add component partials below.
  @import "bootstrap";
SCSS
DARTSASS_INITIALIZER_PATH =
"config/initializers/dartsass.rb"
DARTSASS_MANAGED_HEADER =

‘build_options` is consumed by dartsass-rails as Array#flat_map(&:split), so it MUST be an Array (a String would NoMethodError at build time). We extend dartsass-rails’ own defaults (compressed + no-source-map):

--quiet-deps                   silences warnings from gem load paths
                                (Bootstrap 5.3.x's internal noise:
                                @import / red() / mix() — 311 warns)
--silence-deprecation=import   silences the lone warning on the
                                `@import "bootstrap"` in our own
                                application.bootstrap.scss
                                (Bootstrap 5.3 has no @use replacement)
"# Managed by tsykvas_rails_template:install — re-running install rewrites this file."
DARTSASS_INITIALIZER_BODY =
<<~RUBY.freeze
  # frozen_string_literal: true
  #{DARTSASS_MANAGED_HEADER}

  # tsykvas_rails_template — dartsass-rails build map.
  # Keys are sources under app/assets/stylesheets, values are outputs
  # under app/assets/builds (which Propshaft serves).
  Rails.application.config.dartsass.builds = {
    "application.bootstrap.scss" => "application.css"
  }

  Rails.application.config.dartsass.build_options = [
    "--style=compressed",
    "--no-source-map",
    "--quiet-deps",
    "--silence-deprecation=import"
  ]
RUBY
IMPORTMAP_PINS =
<<~RUBY
  pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap@5.3.3/dist/js/bootstrap.esm.js", preload: true
  pin "@popperjs/core", to: "https://ga.jspm.io/npm:@popperjs/core@2.11.8/lib/index.js", preload: true
RUBY
APPLICATION_JS_PATH =
"app/javascript/application.js"
APPLICATION_JS_BOOTSTRAP_BLOCK =
<<~JS

  // Bootstrap (added by tsykvas_rails_template:install) — exposed globally
  // so OperationsMethods' format.js modal-dismiss path can call it.
  import * as bootstrap from "bootstrap"
  window.bootstrap = bootstrap
JS
PROCFILE_DEV_PATH =
"Procfile.dev"
PROCFILE_DEV_BODY =
<<~PROC
  web: bin/rails server
  css: bin/rails dartsass:watch
PROC