rails / cssbundling-rails

Bundle and process CSS in Rails with Tailwind, PostCSS, and Sass via Node.js.
MIT License
563 stars 83 forks source link

why does `rails new Xyz --css=bootstrap --js=esbuild` not produce working (JS) bootstrap? #113

Closed jasonfb closed 1 year ago

jasonfb commented 1 year ago

Steps to reproduce:

  1. rails new Xyz --css=bootstrap --js=esbuild

  2. generate default controller

rails generate controller Welcome &&
sed -i '' -e 's/class WelcomeController < ApplicationController/class WelcomeController < ApplicationController\n  def index\n\n  end/g' app/controllers/welcome_controller.rb &&
echo "hello world" > app/views/welcome/index.erb &&
sed -i '' -e  's/# root "articles#index"//g' config/routes.rb && 
sed -i '' -e  's/Rails.application.routes.draw do/Rails.application.routes.draw do\n  root to: "welcome#index"/g' config/routes.rb && 
git add . && git commit -m "generates Welcome controller"
  1. to app/views/welcome/index.erb add this basic Navbar:

    <nav class="navbar navbar-expand-lg navbar-light bg-light">
    <a class="navbar-brand" href="#">Navbar</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
    </button>
    
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Dropdown
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <div class="dropdown-divider"></div>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">Disabled</a>
      </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
      <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
    </form>
    </div>
    </nav>
  2. Boot the app with ./bin/dev

result: Javascript interactions do not work bootstrap-no-js

expected result: When I click on the drop-down, the submenu is exposed (JS interactions work) bootstrap-workingjs

Sample app (broken, following steps above): https://github.com/jasonfb/BootstrapTest2

TO BUILD A CORRECTLY WORKING BOOTSTRAP APP STARTING WITH ESBUILD, FOLLOW THESE INSTRUCTIONS

rails new HelloWorld --javascript=esbuild

then adding bundle add "sassc-rails" add css: yarn build:css --watch to Procfile.dev yarn add @popperjs/core bootstrap bootstrap-icons sass In package.json, add to the “scripts” section the bold line:

"scripts": {
  "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets",
  "build:css": "sass ./app/assets/stylesheets/application.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}

IN APP/ASSETS/CONFIG/MANIFEST.JS, REMOVE THIS LINE:

//= link_directory ../stylesheets .css

DELETE THE FILE AT APP/ASSETS/STYLESHEETS/APPLICATION.CSS AND REPLACE IT WITH A FILE APP/ASSETS/STYLESHEETS/APPLICATION.SCSS

@import 'bootstrap/scss/bootstrap';
@import 'bootstrap-icons/font/bootstrap-icons'; 

THEN TO APP/JAVASCRIPT/APPLICATION.JS (YOUR ESBUILD PACK FILE), ADD:

import * as bootstrap from "bootstrap"

TO CONFIG/INITIALIZERS/ASSETS.RB, ADD THIS LINE:

Rails.application.config.assets.paths << Rails.root.join("node_modules/bootstrap-icons/font")

Sample app (working): https://github.com/jasonfb/BootstrapTest3

What is strange to me is that examining my two apps (BootstrapTest2 and BootstrapTest3) I can't see what the difference is why it is working in BootstrapTest3 and not BootstrapTest2

jasonfb commented 1 year ago

I can see based on tutorials on the internet and also based on the wrong answers on this SO post https://stackoverflow.com/questions/71216446/bootstrap-5-1-not-working-in-jsbundling-rails-7

that perhaps this was working once about a year ago? I have been testing against Rails 7.0.4

jasonfb commented 1 year ago

I also tested against Rails 7.0.0 and got the same result. I do not see why others seem to get a different result here,I tried this on two separate machines using Ruby 3.1.3 and Node 16.17.1

jasonfb commented 1 year ago

is the problem here that the JS part of Boostrap just doesn't work with ESBUILD?

If I add back importmaps and then PIN the Bootstrap dependencies, it works.

dhh commented 1 year ago

Can't replicate when using Bootstrap 5.0 example code from here: https://getbootstrap.com/docs/5.0/components/navbar/

Works out of the box with rails new app --css bootstrap -j rebuild.

Looks like the problem is that your HTML contains data attributes not recognized by Bootstrap 5.0. You have:

 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">

You need:

 <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
jasonfb commented 1 year ago

Confirmed--- I was using the example navbar code from Bootstrap 4. My mistake. Thank you @dhh