1

I'm having trouble getting Rails 7 importmaps to play nicely with jquery and bulma.

config/importmap.rb:

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_all_from "app/javascript/controllers", under: "controllers"
pin "bulma", preload: true # @0.9.4
pin "jquery", preload: true # @3.7.0
pin "jquery-ujs", preload: true # @1.2.3
pin "jquery-ui", preload: true # @1.13.2

application.html.erb:

 <head>
  ...
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>

  <%= javascript_importmap_tags %>
  <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
  <%= favicon_link_tag asset_path("favicon.png") %>
  <link rel="shortcut icon" href="../images/fav_icon.png" type="image/x-icon">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
  <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
  <link rel="stylesheet" href="https://unpkg.com/bulma-modal-fx/dist/css/modal-fx.min.css" />
  </head>

app/assets/javascripts/application.js:

import "@hotwired/turbo-rails"
import "controllers"
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
// require lightbox
//= require_tree .
//= require bulma

app/assets/config/manifest.js:

//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../javascripts .js
//= link_tree ../../../vendor/javascript .js
//= link controllers/hello_controller.js
//= link controllers/application.js
//= link controllers/index.js

app/javascript/application.js:

import { Application } from "@hotwired/stimulus"
import "controllers"
import "bulma"
import * as jquery from "jquery"
import "jquery-ujs"
import "jquery-ui"

window.jQuery = jquery
window.$ = jquery

const application = Application.start()

// Configure Stimulus development experience
application.debug = false
window.Stimulus = application

export { application }

app/javascript/controllers/index.js


import { application } from "controllers/application"

import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)

In the javascript console when I try to load my application, it appears as though the bulma styling is working, but jquery is not. I'm seeing "Uncaught ReferenceError: $ is not defined" even though I am setting $ in application.js. There is also another error telling me "Uncaught TypeError: The specifier “controllers/application” was a bare specifier".

enter image description here

This is my first time working with importmap and I love the idea of being able to cut out npm, webpacker, and yarn, but I'm really having a hard time parsing out how all of these files are supposed to work together.

Misha Krul
  • 321
  • 3
  • 13

1 Answers1

0

Cleanup

You can just make a new rails app to see the setup I'm trying to bring you back to.

Delete this file app/assets/javascripts/application.js, can't have two application.js.

Already covered by //= link_tree ../../javascript .js, so don't need these:

//= link controllers/hello_controller.js
//= link controllers/application.js
//= link controllers/index.js

I don't know why you're copying stimulus initialization, it already happens in controllers directory.

// app/assets/javascripts/application.js

import "jquery"
import "@hotwired/turbo-rails"
import "controllers"

We're using Turbo, not turbolinks. No Rails UJS in rails 7, and you really don't want to bring that back in.


Jquery

No need to download, just pin it:

bin/importmap pin jquery -f jsdelivr

https://stackoverflow.com/a/72290313/207090

Bulma

Bulma is css:

<!-- app/views/layouts/application.html -->

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">

or import (this is a plain css import that browser should take care of):

/* app/assets/stylesheets/application.css */

@import "https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css";

Importmaps

This ends up in the browser in <script type="importmap"> tag. (see how controllers are already there):

$ bin/importmap json
{
  "imports": {
    "application":                  "/assets/application-c053fb992232353f27edaf9cd84a9062ed61672b85c0a69952d917f7488ff554.js",
    "@hotwired/turbo-rails":        "/assets/turbo.min-f309baafa3ae5ad6ccee3e7362118b87678d792db8e8ab466c4fa284dd3a4700.js",
    "@hotwired/stimulus":           "/assets/stimulus-1bd52683afde5c8ff5572f5d49429cea5bf7744ca636fcb830c015d8cccf353e.js",
    "@hotwired/stimulus-loading":   "/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js",
    "jquery":                       "https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.js",
    "controllers/application":      "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js",
    "controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js",
    "controllers":                  "/assets/controllers/index-16af318b40862c438fd6ca780240ce4730b8591e53dc53315b75f360435cf905.js"
  }#    ^                             ^
}  #    |                             |
   #  names you use to import        urls browser uses to get it
   #    |                             ^ 
   #    |                             |
   #    `------>  mapped to  ---------'

This json is what you're building with pin and pin_all_from commands in config/importmap.rb. If you don't see something there you can't import it, unless you're using full urls:

import "jquery";
// works, because it is mapped to a jsdelivr url

// without an import-map you can do this
import "https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.js";

Same thing for your local files, they have to be mapped, or in rails terms pinned. That process goes through sprockets to locate files. But I think I've covered it here:

https://stackoverflow.com/a/72855705/207090

Alex
  • 16,409
  • 6
  • 40
  • 56