I am a new to rails and struggling to get Jquery and Bootstrap to work with Rails 6. I think it has something to do with switching the app from rails 5 to rails 6 and using webpacker to load Jquery rather than loading it as a gem. I have gone through the instructions for this however it still doesn't seem to work properly. Someone helped me with a more specific problem and got me to paste this into the view which then seemed to make it work:
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
However, this feels like a workaround and I want Jquery available in all views. Below is a copy of /javascript/packs/application.js :
require("jquery")
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("bootstrap/dist/js/bootstrap")
import '../stylesheets/application'
import './bootstrap_custom.js'
//= require jquery3
//= require popper
//= require bootstrap-sprockets
and /config/webpack/environment.js:
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery/src/jquery',
jQuery: 'jquery/src/jquery'
})
)
module.exports = environment
I don't get the difference between Require("...")
and //= require ...
? is the //=
a legacy notation that should be converted to Require("...")
?
Also do I need both require("jquery")
and //= require jquery3
? I assume not. If so which one should I delete?
In /apps/views/layouts/Application.html.erb I have the following contained within the header:
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
Bootstrap 5 is designed to be used without jQuery, but it's still possible to use our components with jQuery. If Bootstrap detects jQuery in the window object it'll add all of our components in jQuery's plugin system; this means you'll be able to do $('[data-bs-toggle="tooltip"]').
I struggled with this for days, so hopefully my experience will help you :)
First of all, you will be loading jQuery and Bootstrap as a webpack module, so you don't need any of this:
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
Instead, you want to install the modules using yarn
on your prompt:
$ yarn add jquery bootstrap
After that, you should import jQuery into your project. The safest way to do it is editing your /config/webpack/environment.js, much in the way you did:
...
environment.plugins.append('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
...
Now, since you're importing jQuery as a webpack global plugin (that is, available throughout all your views, and even from other modules), then you should not import it again in your app/javascript/packs/application.js
, as this is a known cause for unexpected behavior. In that file you do want, however, to import Bootstrap. So it should look like this:
# app/javascript/packs/application.js
import 'bootstrap';
import '../stylesheets/application'
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
Note that I'm using the import 'module'
syntax, which is preferred over the older require("")
syntax. And you definitely don't want to use any of these:
//= require jquery3
//= require popper
//= require bootstrap-sprockets
They're Sprockets (asset pipeline) directives with no use in Webpack-land.
So, by now you have both jQuery and Bootstrap js imported into your project, but you're still missing Bootstrap stylesheet. In order to import it, just include this in your application.scss
(which I assume you're using given you're importing it with import '../stylesheets/application'
):
# application.scss
@import "~bootstrap/scss/bootstrap";
And there you are, jQuery and Bootstrap imported into your project. Hope it helps! If you're new to Webpack (as I am) you will encounter lots of obstacles before you can fully use it, since there are a lot of differences with the asset pipeline. After several days (if not weeks) of research I've managed to deal with most of them, so feel free to look into my question history to see if you find some useful answers.
Additional info:
$ yarn add popper.js
in your command line, and edit your /config/webpack/environment.js so it looks like this:environment.plugins.append('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
})
)
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With