Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 7, 2022 06:13 pm GMT

Upgrading from Rails 6.x Webpacker to Rails 7 Importmaps

I've spend a good part of the last few months trying to figure out how I was going to convert my three semi-private Rails 6.1.x apps to Rails 7. I created a bunch of Rails 7 test apps using ESbuild, Importmaps and even Webpacker. While ESbuild may of been an eaiser path (basically node modeles without webpacker stuff), I leaned towards Importmaps. Other than a few node package I used, almost all of my JS was using Stimulus in some form.

So I marched on with my journey to Rails 7. Along the way I did do a lot of refactoring. I've been moving slowly from W3css to Tailwind.css. I already had the mixed css with some of my own scss. I don't think I'll remember all the steps I took, but I try to decribe the steps I took in some kind of order. It may not be the best way, but I did it my way and it worked

Rail7 Branch

I created and checked out a new rails7 branch. Fortunally I didn't have to make any changes to my deployed master, but merging branches was always in the back of my mind.

I then did bin/rails app:update and it did its thing. I hate to admint this, but I have No tests. I've tried many times to get into the test mode, but failed! So I continued to test how I've tested for the last 40 years! Change something then push the car back up the hill and see if the brakes fail again!!

I can't remember if development worked after the update, but I think it did. The gem 'sass-rails' was still in the Gemfile
so I think it worked.

I did have a problem with the update adding ActiveStorage migrations. Apperently I never installed ActiveStorge and really didn't want to. I set config.active_record.migration_error = false to avoid the error and later on changed require "rails/all" to the documentation way to not require ActiveStorage.

Onward to the next step, Rip out Webpacker and convert Gemfile to a fresh Rails 7 Importmaps version.

Rip out Webpacker.

Seemed scary but pretty simple. I removed:

  • app/javascript/application.css
  • app/javascript/channels/consumer.js
  • app/javascript/channels/index.js
  • app/javascript/packs/application.js
  • babel.config.js
  • bin/spring
  • bin/webpack
  • bin/webpack-dev-server
  • bin/yarn
  • config/webpack/development.js
  • config/webpack/environment.js
  • config/webpack/production.js
  • config/webpack/test.js
  • config/webpacker.yml
  • package-lock.json
  • postcss.config.js
  • yarn.lock

I then basically merged my orginal Gemfile with the Test App Gemfile. The main stuff being (without my specifics):

gem "rails", "~> 7.0.0"# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]gem "sprockets-rails"# Use postgresql as the database for Active Recordgem "pg", "~> 1.1"# Use the Puma web server [https://github.com/puma/puma]gem "puma", "~> 5.0"# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails]gem "importmap-rails"# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]gem "turbo-rails"# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]gem "stimulus-rails"# Use Tailwind CSS [https://github.com/rails/tailwindcss-rails]gem "tailwindcss-rails"# Build JSON APIs with ease [https://github.com/rails/jbuilder]gem "jbuilder"gem "redis", "~> 4.0"

I think at this point development worked, but maybe a few errors/problems with css.

SASS CSS, etc

I had a bunch of crap scss. Some problably hadn't been used in years and never found a good way of identifing what wasn't used. I knew the main things I used were colors, buttons, tables and a few almost components. I converted that scss to css with one of the many scss_to_css sites found on the web and added that css to my branch.

Stimulus Controller needed to be converted to the @hotware version. import { Controller } from "@hotwired/stimulus"

I added to config/importmap.rb my unique CDNs

pin "application", preload: truepin "@hotwired/turbo-rails", to: "turbo.min.js", preload: truepin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: truepin_all_from "app/javascript/controllers", under: "controllers"pin "stimulus-flatpickr", to: "https://ga.jspm.io/npm:[email protected]/dist/index.m.js"pin "flatpickr", to: "https://ga.jspm.io/npm:[email protected]/dist/flatpickr.js"pin "stimulus-autocomplete", to: "https://ga.jspm.io/npm:[email protected]/src/autocomplete.js"pin "@hotwired/stimulus", to: "https://ga.jspm.io/npm:@hotwired/[email protected]/dist/stimulus.js"

I also had to add a link to my layout for flatpickr link rel="stylesheet" href="https://ga.jspm.io/npm:[email protected]/dist/flatpickr.min.css"

CSS bundling starting working with some problems. Many of them related to the config/tailwind.js file.

I merged my old tailwing config file with the new verssion

const defaultTheme = require('tailwindcss/defaultTheme')module.exports = {  content: [    './app/helpers/**/*.rb',    './app/javascript/**/*.js',    './app/views/**/*.html.*',    './app/components/**/*.html.*'  ],  theme: {    extend: {      fontFamily: {        sans: ['Inter var', ...defaultTheme.fontFamily.sans],      },      colors: {        'orange': '#ffa500',        'malt': '#991A1E',        'gold': '#A79055',        'dark-blue': '#0F3E61',        'success': '#63ed7a',        'secondary': "#9db3b8",        'w3green': "#4CAF50",        'w3red': "#f44336",        'blue-link': "#00c",        lime: {          lightest: '#f1fff1',          lighter: '#e2ffe2',          light: '#c9ffc9',          DEFAULT: '#b8ffb8',          dark: '#96ff96',          darker: '#7cff7c',          darkest: '#49ff49',        },        // gray: colors.trueGray,        green: {          lighter:'hsla(122, 59%, 64%, 1)',          light: 'hsla(122, 49%, 54%, 1)',          DEFAULT: 'hsla(122, 39%, 49%, 1)',          dark: 'hsla(122, 39%, 39%, 1)',          darker: 'hsla(122, 39%, 29%, 1)',        },      },    },  },  plugins: [    require('@tailwindcss/forms'),    require('@tailwindcss/aspect-ratio'),    require('@tailwindcss/typography'),  ]}

I have a few Web Components and needed to add that folder to the content: array

I also had some tailwind webpack components the used @apply and converted them to rails helpers. Something like:

module ComponentsHelper  def greenBox    "box-border box-content m-3 p-4 bg-green-300 border-green-100 border-2 text-black"  end  def blueBox    "box-border box-content m-3 p-4 bg-blue-400 border-blue-200 border-2 text-black"  end  def btn    "py-1 px-2 text-black hover:text-white rounded font-lg font-bold "  end  def btnInfo    btn + "bg-blue-400 text-blue-link hover:text-blue-100"  end  def btnWarn    btn + "bg-orange hover:text-yellow-200"  end  def btnGreen    btn + "bg-green-500 hover:text-green-100"  end  def btnDanger    btn + "bg-red-500 hover:text-red-200"  end  def btnSuccess    btn + "bg-success hover:bg-green-700"  end  def btnSecondary    btn + "bg-secondary"  end  def flashAlert(type)    case type    when 'danger'      return "bg-red-200 text-red-600"    when 'info'      return "bg-blue-200 text-blue-600"    when 'success'      return "bg-green-200 text-green-600"    when 'warning'      return "bg-yellow-400 text-yellow-800"    else      return "bg-gray-200 text-gray-600"    end  end  def destroyConfirmTag(model,confirm_msg:"",klass:"",prompt:"")    klass= "#{btnDanger} inline-block" if klass.blank?    confirm_msg = "Are You Sure?" if confirm_msg.blank?    prompt = "Delete #{model.class.name}" if prompt.blank?    node = content_tag(:div, class: klass,      data:{        controller:"destroyConfirm",         action:"click->destroyConfirm#confirm",        destroyConfirm_cmsg_value:confirm_msg      }){      concat(tag.span(prompt))      concat(button_to( '',model, method: :delete,class:"hidden",data:{destroyConfirm_target:"submit"}))    }    node   endend

The last helper destroyConfirmTag tackled the problem with Rails removing the method::get from delete scaffold. The default change is to change link_to to button_to. But it didn't have a confirm tag. So I just call this on delete links and add back the confirm message. I have a couple delete links that I need to sure they didn't click the wrong link. There is a simple stimulus controller:

import { Controller } from "@hotwired/stimulus"export default class extends Controller {  static targets = [ "submit"]  static values = { cmsg: String}  connect() {    // console.log("destroy confirm")    if (this.hasCmsgValue) {      this.confirm_msg = this.cmsgValue    }else{      this.confirm_msg  = "Are you sure?"    }  }  confirm(){    // console.log(this.submitTarget.closest('form'))    let ans = confirm(`${this.confirm_msg}`)    if (ans == true) {      this.submitTarget.closest('form').submit()    }  }}

I even toyed with simple Ruby class to generate css from tailwind config file - never finished or used it though. Think I saw some post the the rails_tailwind gem site bitching about colors and components.

class TwColors  attr_accessor :colors, :css  Colors = {:colors=>                                                    {:orange=>"#ffa500",                                         :malt=>"#991A1E",                                           :gold=>"#A79055",                                           :"dark-blue"=>"#0F3E61",                                    :lime=>                                                      {:lightest=>"#f1fff1",                                       :lighter=>"#e2ffe2",                                        :light=>"#c9ffc9",                                          :DEFAULT=>"#b8ffb8",                                        :dark=>"#96ff96",                                           :darker=>"#7cff7c",                                         :darkest=>"#49ff49"},   :green=>    {:lighter=>"hsla(122, 59%, 64%, 1)",     :light=>"hsla(122, 49%, 54%, 1)",     :DEFAULT=>"hsla(122, 39%, 49%, 1)",     :dark=>"hsla(122, 39%, 39%, 1)",     :darker=>"hsla(122, 39%, 29%, 1)"}}}  def initialize()    @colors = Colors    @css = "not parsed yet 
" @colors[:colors].each do |k,v| unless v.is_a?(Hash) add_color_classes(k,v) else add_nested_color_classes(k,v) end end puts @css end def add_color_classes(k,v) @css << ".text-#{k} {
color: #{v};
}" @css << ".bg-#{k} {
background-color: #{v};
}
" end def add_nested_color_classes(k,v) v.each do |kk,vv| if kk.to_s == "DEFAULT" add_color_classes("#{k}",vv) else add_color_classes("#{k}-#{kk}",vv) end end endend

Merging rails7 branch with master

One of my major fears was -> What if I merged and Capistrono would not deploy. I spent way too much time trying to figure out how to deploy a branch to my staging server. I found posts on how to do it (old) and nothing worked.

I then just faked it and ran staging locally.

  • set staging DB to point to develoment
  • bin/rails assets:precompile
  • bin/rails s -e staging

This was where I found I had the bundling issues with css classes in components not being picked up. After a little tuning things were working fine.

Had to remember to bin/rails assets:clobber when I moved back to development.

Everything seemed to be working fine, especially after a bunch of refactoring. It was time to merge. Made sure I had a backup clone of my repo and did a merge after I figured out how to do it (I've been using the OSX version of Fork and am not proficient with git or Fork.

Devepment worked fine, as expected.

cap staging deploy also worked without any changes to the Capistrono config file.

Played with it with a few more refactoring tweeks and the deployed to production!

and I'm fine and

I'm on Rails 7 without any Webpacker crap!!!


Original Link: https://dev.to/salex/upgrading-from-rails-6x-webpacker-to-rails-7-importmaps-59jo

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To