Search code examples
jqueryruby-on-railsrubyruby-on-rails-7import-maps

Rails 7 Semantic-UI jQuery "Uncaught ReferenceError" Using Importmaps


Issue Summary

I have a new rails 7 application which is using the importmap-rails gem to manage the javascript frontend libraries.

I am attempting to use the Semantic-UI library, but the dependency for jQuery is not being recognized by the Semantic-UI javascript.

I was unable to pin the Semantic-UI library via importmap, so I added this library to the importmap.rb manually. Here is a link the cdn for semantic.min.js I am using.

The following error message appears in the console on Chrome Web Tools and the collapsible accordions are not functioning that I have on the page to validate the javascript.

Uncaught ReferenceError: jQuery is not defined
    at semantic.min.js:11:6043
(anonymous) @ semantic.min.js:11

The line being referenced in semantic.min.js looks like this

(jQuery,window,document)

Attempted Fixes

I thought potentially the order in which the Semantic-UI and jQuery import was happening could be the issue (per a number of other Stack Overflow questions and Github issues ).

However, I have the jQuery import occurring prior to the Semantic-UI import.

If I comment out the Semantic-UI import, I am able to use jQuery without an issue.

I have toggled the preload variable on the importmap.rb file to see if Semantic-UI is being loaded too quickly as well.

I have attempted renaming the jQuery import to be $ and jQuery, but neither of those end up being recognized.

My gut says that Semantic-UI is loading before jQuery is set as a global variable, but I am not sure how that works with the new importmap features and the asset pipeline.

Application Configuration

Importmap.rb

# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin "jquery", to: "https://ga.jspm.io/npm:[email protected]/dist/jquery.js", preload: true
pin "semantic-ui", to: "https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"

pin_all_from "app/javascript/controllers", under: "controllers"

Application.js

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "jquery" 
import "semantic-ui"

index.html.erb collaspible accordians

<div class="ui styled accordion">
  <div class="title">
    <i class="dropdown icon"></i>
    What is a dog?
  </div>
  <div class="content">
    <p class="transition hidden">A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world.</p>
  </div>
  <div class="title active">
    <i class="dropdown icon"></i>
    What kinds of dogs are there?
  </div>
  <div class="content active">
    <p class="transition visible">There are many breeds of dogs. Each breed varies in size and temperament. Owners often select a breed of dog that they find to be compatible with their own lifestyle and desires from a companion.</p>
  </div>
  <div class="title">
    <i class="dropdown icon"></i>
    How do you acquire a dog?
  </div>
  <div class="content">
    <p>Three common ways for a prospective owner to acquire a dog is from pet shops, private owners, or shelters.</p>
    <p>A pet shop may be the most convenient way to buy a dog. Buying a dog from a private owner allows you to assess the pedigree and upbringing of your dog before choosing to take it home. Lastly, finding your dog from a shelter, helps give a good home to a dog who may not find one so readily.</p>
  </div>
</div>

Gem File

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.0.1"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.0"

# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
gem "sprockets-rails"
gem "semantic-ui-sass"

# Use postgresql as the database for Active Record
gem "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"

# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder"

# Use Redis adapter to run Action Cable in production
# gem "redis", "~> 4.0"

# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"

# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
# gem "bcrypt", "~> 3.1.7"

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]

# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false

# Use Sass to process CSS
# gem "sassc-rails"

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"

group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", platforms: %i[ mri mingw x64_mingw ]
end

group :development do
  # Use console on exceptions pages [https://github.com/rails/web-console]
  gem "web-console"

  # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler]
  # gem "rack-mini-profiler"

  # Speed up commands on slow machines / big apps [https://github.com/rails/spring]
  # gem "spring"
end

group :test do
  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
  gem "capybara"
  gem "selenium-webdriver"
  gem "webdrivers"
end


Solution

  • I resolved this issue by manually updating the source for jquery pinned in importmap.rb from the source that the original bin/importmap pin jquery pointed at which was:

    https://ga.jspm.io/npm:[email protected]/dist/jquery.js

    to now be

    https://code.jquery.com/jquery-3.6.0.min.js

    Additionally, I added some jquery code to application.js to run when the document is loaded (per the documentation on Semantic-UI's website

    $(document).ready(function(){
      $('.ui.accordion').accordion()});