I recently got rid of webpacker and installed importmap and turbo. My Stimulus JS controllers are not rendering anything.
importmap.rb :
# Pin npm packages by running ./bin/importmap
pin "application", 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 "#hotwired/turbo-rails", to: "turbo.js", preload: true
typewriter_controller.js :
import { Controller } from "#hotwired/stimulus"
export default class extends Controller {
connect() {
// some code...
}
}
application.html.erb:
<head>
some stuff..
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag "turbo", type: "module-shim" %>
<%= javascript_importmap_tags %>
</head>
I tried to re-install the stimulus gem but it didn't work. I'm running out of ideas on this one.
As from the stimulus-rails installation guide, I would check the following files are configured this way:
In app/javascript/controllers/index.js
import { application } from "controllers/application"
// Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from "#hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)
In app/javascript/controllers/application.js
import { Application } from "#hotwired/stimulus"
const application = Application.start()
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
export { application }
In app/javascript/application.js
import "controllers"
This assumes you are indeed using importmap and not some other JavaScript bundler (e.g., yarn).
Related
i downloaded this template here https://bootstrapmade.com/regna-bootstrap-onepage-template/
my goal is to get it going in rails 7. i copied the content of index.html to experiment.erb.html.
And i copied the javascript content to app javascript.
my importmap.rb looks like this
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 "bootstrap", to: "https://ga.jspm.io/npm:bootstrap#5.1.3/dist/js/bootstrap.esm.js"
pin "#popperjs/core", to: "https://unpkg.com/#popperjs/core#2.11.2/dist/esm/index.js" # use unpkg.com as ga.jspm.io contains a broken popper package
pin_all_from "app/javascript/aos", under: "aos"
pin_all_from "app/javascript/purecounter", under: "purecounter"
pin_all_from "app/javascript/glightbox", under: "glightbox"
pin_all_from "app/javascript/isotope", under: "isotope"
pin_all_from "app/javascript/swiper", under: "swiper"
pin_all_from "app/javascript/main", under: "main"
my application.js looks like this:
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import '#hotwired/turbo-rails';
import 'controllers';
import 'bootstrap';
import 'aos/aos';
import 'purecounter/purecounter_vanilla';
import 'glightbox/glightbox';
import 'isotope/isotope';
import 'swiper/swiper-bundle.min';
import 'main/main';
My error message in chrome browser is
aos-75b913982a069d95d17deb4a5fa63c1019abfca2c7bad6623a03e046e1e8dd31.js:1 Uncaught TypeError: Cannot set properties of undefined (setting 'AOS')
at aos-75b913982a069d95d17deb4a5fa63c1019abfca2c7bad6623a03e046e1e8dd31.js:1:182
at aos-75b913982a069d95d17deb4a5fa63c1019abfca2c7bad6623a03e046e1e8dd31.js:1:187
(anonymous) # aos-75b913982a069d95d17deb4a5fa63c1019abfca2c7bad6623a03e046e1e8dd31.js:1
(anonymous) # aos-75b913982a069d95d17deb4a5fa63c1019abfca2c7bad6623a03e046e1e8dd31.js:1
[filestructure in vscode1
if you know what i have to fix, please explain.
I need help with following code:
Rails 7.0.3
view.html.erb
<div id="calendar"></div>
importmap.rb
pin "fullcalendar", to: "https://ga.jspm.io/npm:fullcalendar#5.11.0/main.js"
javascript/application.js
import "fullcalendar"
javascript/controllers/fullcalendar_controller.js
import { Controller } from "#hotwired/stimulus"
import FullCalendar from 'fullcalendar'
export default class extends Controller {
connect() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth'
});
calendar.render();
}
}
layouts/applications.html.erb
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
And the output... :(
Failed to register controller: fullcalendar (controllers/fullcalendar_controller)
ReferenceError: exports is not defined
at main.js? [sm]:20877:37*
Any help would be appreciated
The issue is with calendar js file, you can download the fullcalendar js file to your local project, ./bin/importmap pin fullcalendar --download and then you can see fullcalendar.js file under vendors directory vendors/javascript/fullcalendar.js then replace that js file content with the full_calendar source https://cdn.jsdelivr.net/npm/fullcalendar-scheduler#5.11.2/main.js finally add export line to end of the fullcalendar.js file export default FullCalendar;. Hope it may help you with your issue.
I am using Rails 7 with importmap and esbuild. The assets:precompile task succeed but when I open the webpage I see this in JS console
GET https://staging.example.com/assets/src/jquery net::ERR_ABORTED 404
GET https://staging.example.com/assets/utility/direct_upload
net::ERR_ABORTED 404 GET
https://staging.example.com/assets/utility/manual_keywords
net::ERR_ABORTED 404 GET https://staging.example.com/assets/src/toastr
net::ERR_ABORTED 404 GET
https://staging.example.com/assets/utility/modals net::ERR_ABORTED 404
GET https://staging.example.com/assets/controllers net::ERR_ABORTED
404 GET https://staging.example.com/assets/custom/init
net::ERR_ABORTED 404 GET
https://staging.example.com/assets/custom/dropdown net::ERR_ABORTED
404 https://staging.example.com/assets/custom/notification
net::ERR_ABORTED 404
app/assets/config/manifest.js
//= link_tree ../images
//= link_tree ../builds
app/assets/javascript/application.js
require('#rails/ujs').start();
import "#hotwired/turbo-rails"
import * as ActiveStorage from "#rails/activestorage"
ActiveStorage.start()
import "./src/jquery"
import Popper from "popper.js"
import 'bootstrap'
import dataTable from 'datatables.net-bs4'
dataTable(window, $)
import "chartkick"
import "chart.js"
import "./src/toastr"
import './utility/direct_upload'
import 'utility/manual_keywords'
import './utility/modals'
import "./controllers"
import './custom/init'
import './custom/dropdown'
import './custom/notification'
config/importmap.rb
pin "application", preload: true
pin "#hotwired/turbo-rails", to: "https://ga.jspm.io/npm:#hotwired/turbo-rails#7.1.3/app/javascript/turbo/index.js"
pin "#hotwired/turbo", to: "https://ga.jspm.io/npm:#hotwired/turbo#7.1.0/dist/turbo.es2017-esm.js"
pin "#rails/actioncable/src", to: "https://ga.jspm.io/npm:#rails/actioncable#7.0.3/src/index.js"
pin "#rails/activestorage", to: "https://ga.jspm.io/npm:#rails/activestorage#6.0.5/app/assets/javascripts/activestorage.js"
pin "popper.js", to: "https://ga.jspm.io/npm:popper.js#1.16.1/dist/umd/popper.js"
pin "bootstrap", to: "https://ga.jspm.io/npm:bootstrap#4.6.1/dist/js/bootstrap.js"
pin "jquery", to: "https://ga.jspm.io/npm:jquery#3.6.0/dist/jquery.js"
pin "datatables.net-bs4", to: "https://ga.jspm.io/npm:datatables.net-bs4#1.12.1/js/dataTables.bootstrap4.js"
pin "datatables.net", to: "https://ga.jspm.io/npm:datatables.net#1.12.1/js/jquery.dataTables.js"
pin "chartkick", to: "https://ga.jspm.io/npm:chartkick#4.2.0/dist/chartkick.js"
pin "toastr", to: "https://ga.jspm.io/npm:toastr#2.1.4/toastr.js"
pin "chart.js", to: "https://ga.jspm.io/npm:chart.js#3.8.0/dist/chart.esm.js"
package.json
"scripts": {
"build": "node esbuild.config.js",
"build:css": "sass ./app/assets/stylesheets/application.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
esbuild.config.js
const path = require('path')
const rails = require('esbuild-rails')
require("esbuild").build({
entryPoints: ["application.js"],
bundle: true,
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/assets/javascript"),
watch: process.argv.includes("--watch"),
//inject: ["inject-jquery.js"],
plugins: [rails()]
}).catch(() => process.exit(1))
layout.html
<%#javascript_include_tag "application", "data-turbo-track": "reload"%>
<%= javascript_importmap_tags %>
Climbing the learning curve with Webpacker and Rails 6.
I've installed Boostrap 4 using Yarn and Webpacker. When I try play with Bootstrap components in a browser's JS console then I get: TypeError: $.fn.button is undefined.
If I remove the Yarn installation add a Bootstrap CDN link in the head of the HTML (the old way) everything works fine. When I remove the CDN links and revert to using Webpacker I get back to the error above.
Here is my Webpacker setup:
// package.json
{
"name": "depot",
"private": true,
"dependencies": {
"#rails/actioncable": "^6.0.0-alpha",
"#rails/activestorage": "^6.0.0-alpha",
"#rails/ujs": "^6.0.0-alpha",
"#rails/webpacker": "^4.0.7",
"bootstrap": "4.2.1",
"jquery": "^3.4.1",
"popper.js": "^1.15.0",
"turbolinks": "^5.2.0"
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "^3.8.0"
}
}
// enviornment.js
const { environment } = require("#rails/webpacker");
const webpack = require("webpack");
environment.plugins.append(
"Provide",
new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery',
Popper: ["popper.js", "default"]
})
);
module.exports = environment;
// application.js
require("#rails/ujs").start();
require("turbolinks").start();
require("#rails/activestorage").start();
require("channels");
require("jquery");
require("bootstrap");
import "./src/application.scss";
# layouts/application.html.haml
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}
%title Depot
= csrf_meta_tags
= csp_meta_tag
= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
Is there something I should be doing to export the Bootstrap functions to the global namespace?
Found a forum where this was discussed: https://gorails.com/forum/how-to-use-bootstrap-with-webpack-rails-discussion
They mentioned it could be caused by having jQuery loading multiple times, with the latest declaration preventing Bootstrap's JS from loading. I couldn't find any evidence of this in my project.
For me the fix ended up being a few lines added to the webpack entry point that exposed jQuery to the browser:
# packs/application.js
import JQuery from 'jquery';
window.$ = window.JQuery = JQuery;
I noticed even I removed require 'jquery' from applications.js, jquery still appears in the compiled application.js, so I removed this from enviroment.js
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery',
and add this to application.js
import JQuery from 'jquery';
window.$ = window.JQuery = JQuery;
restart rails server, it works!
If you want to know why see this answer
I am using the serviceworker-rails gem to make my eCommerce application a progressive web app. Here is a gem file snippet from the project;
# progressive web application gem
gem 'serviceworker-rails'
# eCommerce gems
gem 'solidus'
gem 'solidus_auth_devise'
#base gems
gem 'rails', '~> 5.2.0'
ruby '2.5.1'
the serviceworker-rails gem in turn generates the manifest files needed to make the app a progressive web application;
app/assets/javascripts/serviceworker.js.erb
var CACHE_VERSION = 'v1';
var CACHE_NAME = CACHE_VERSION + ':sw-cache-';
function onInstall(event) {
console.log('[Serviceworker]', "Installing!", event);
event.waitUntil(
caches.open(CACHE_NAME).then(function prefill(cache) {
return cache.addAll([
// make sure serviceworker.js is not required by application.js
// if you want to reference application.js from here
'<%#= asset_path "application.js" %>',
'<%= asset_path "application.css" %>',
'/offline.html',
]);
})
);
}
function onActivate(event) {
console.log('[Serviceworker]', "Activating!", event);
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.filter(function(cacheName) {
// Return true if you want to remove this cache,
// but remember that caches are shared across
// the whole origin
return cacheName.indexOf(CACHE_VERSION) !== 0;
}).map(function(cacheName) {
return caches.delete(cacheName);
})
);
})
);
}
// Borrowed from https://github.com/TalAter/UpUp
function onFetch(event) {
event.respondWith(
// try to return untouched request from network first
fetch(event.request).catch(function() {
// if it fails, try to return request from the cache
return caches.match(event.request).then(function(response) {
if (response) {
return response;
}
// if not found in cache, return default offline content for navigate requests
if (event.request.mode === 'navigate' ||
(event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
console.log('[Serviceworker]', "Fetching offline content", event);
return caches.match('/offline.html');
}
})
})
);
}
self.addEventListener('install', onInstall);
self.addEventListener('activate', onActivate);
self.addEventListener('fetch', onFetch);
app/assets/javascripts/serviceworker-companion.js
if (navigator.serviceWorker) {
navigator.serviceWorker.register('/serviceworker.js', { scope: './' })
.then(function(reg) {
console.log('[Companion]', 'Service worker registered!');
});
}
The application does not raise up any errors; just that I happen to notice that the service worker is not being registered. Here is the manifest in use;
app/assets/javascripts/manifest.json.erb
{
"name": "My Progressive Rails App",
"short_name": "Progressive",
"start_url": "/"
}
...and finally;
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Istore</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<link rel="manifest" href="/manifest.json" />
<meta name="apple-mobile-web-app-capable" content="yes">
</head>
<body>
<%= yield %>
</body>
</html>
To be fair; I have used this set up before and it worked good. Something breaks when I use it with solidus_gem. So far; my efforts to debug the issue has only zeroed me in on a set of probabilities. The strongest being; lack of a root directive.
(the gem also doesn't work for the default rails starter page)
But upon setting a custom root page; the gem works. So I did some monkey patching and added the solidus' root page to my project then appended the application routes to include the solidus home page.
config/routes.rb
Rails.application.routes.draw do
root to: 'spree/home#index'
mount Spree::Core::Engine, at: '/'
end
This has proven unsuccessful. I am using lighthouse to audit the application and the error signifies that the serviceworker is not being registered.
What am I missing? Is something out of scope?
I finally got it to work :) . The gem supplying the application layout is solidus but the problem is that the manifest is in the local application within which solidus is a gem.
To make it visible to the gem; I removed the tags from
app/views/layouts/application.html.erb
and then put them in the gems layout file. You have to download it locally to make changes. The layout file as of writing this is at
app/views/spree/layouts/
but the head section contains a render of a _head partial at
app/views/spree/shared/_head.html.erb
from where it is more efficient to place these tags inside to resolve the issue.
<%= javascript_include_tag "application" %>
<link rel="manifest" href="/manifest.json" />
<meta name="apple-mobile-web-app-capable" content="yes">