1

I'm currently migrating an ES6 project from Bootstrap 4 to Bootstrap 5 and get this error:

Uncaught TypeError: bootstrapElement.Tooltip is not a function

As stated in the Migration Notes, Bootstrap 5 has dropped the default integration of jQuery. However, Bootstraps jQuery plugins will still be loaded, if jQuery is detected in the window object.

In my case, I import jQuery, but Bootstrap does not seem to detect it:

import $ from "jquery";
import {Tooltip} from "bootstrap";
import {getjQuery} from "bootstrap/js/src/util";

...

console.log(getjQuery()); // Returns null
bootstrapElement.Tooltip({ title: "Element Tooltip" }); // Throws the above error

But even if I try to load jQuery into the window object manually, the error occurs:

if(!getjQuery()) {
    window.jQuery = window.$ = $;
}
console.log(getjQuery()); // Returns jQuery now
bootstrapElement.Tooltip({ title: "Element Tooltip" }); // It still throws the error

I guess this is because I load jQuery into window after the import of Tooltip and the plugin would be loaded during the import. Which it won't, because jQuery is not set to window yet.

I'm aware that I could use the plugin directly by using

let elementTooltip = new Tooltip(bootstrapElement, { title: "Element Tooltip" });
elementTooltip.show();

instead of

bootstrapElement.Tooltip({ title: "Element Tooltip" });
bootstrapElement.Tooltip("Show");

but then I encounter problems later when I try to remove the tooltip again, because I can't access elementTooltip anymore and creating a new instance won't do the trick. Resolving this would mean a lot of work in the architecture of the project (mostly because this is not the only plugin I use) and I'd like to avoid that.

Is there a possibility to import jQuery in a way that Bootstrap 5 is able to detect it and load its jQuery plugin?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
StoryTeller
  • 1,673
  • 12
  • 30

2 Answers2

2

I ended up using expose-loader.

After the installation through npm,

npm install expose-loader --save-dev

you can expose your module to global variables. This means in my case: I can load jQuery, so Bootstrap has access to it.

// File entry.js
import $ from "expose-loader?exposes=$,jQuery!jquery";

Afterwards, the bootstrap plugins will also be available in jQuery when you import them:

import {Tooltip} from "bootstrap";
bootstrapElement.tooltip({ title: "Element Tooltip" });

Note that tooltip is lowercase. In the Bootstrap documentation, it's uppercase, but for some reason it's loaded in lowercase.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
StoryTeller
  • 1,673
  • 12
  • 30
0

Bootstrap is pretty clear that you must have the jQuery property defined on the window object.

So you need to define that property (properly) before Bootstrap loads.

Here are a couple of ways you could achieve that:

Load jQuery separately

Rather than importing jQuery, load it as a separate resource (like it's 2007) and treat it as a window global that's already defined. You might be able to make life a little easier via an alias for "jquery" that points to a module that just exports window.jQuery.

It's not ideal for a number of reasons, but it solves your problem.

Load a jQuery module (which sets window.jQuery) before you load Bootstrap.

This is a bit trickier just because Webpack is all about not needing to manage load order, but it helps to know that Webpack will evaluate modules based on the order in which they are imported.

Add a new module named something like "SetjQueryGlobal" and then import it into your entry point:

// SetjQueryGlobal.js
import $ from "jquery";
window.jQuery = $;

// entry.js
import "./SetjQueryGlobal";
import $ from "jquery";
import {Tooltip} from "bootstrap";

bootstrapElement.Tooltip({ title: "Element Tooltip" });

Webpack will evaluate your SetjQueryGlobal module, including setting the window property, before it moves on to loading Bootstrap.

This is probably the approach I'd recommend, however a lot depends on your setup and there isn't enough information to say that this is definitely the right solution for you.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JDB
  • 25,172
  • 5
  • 72
  • 123