简体   繁体   中英

How do I load the Bootstrap 5 jQuery plugins in an ES6 project using webpack?

I'm currently migrating an ES6 project from Bootstrap 4 to Bootstrap 5 and got 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" }); // 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 any possibility to import jQuery in a way that Bootstrap 5 is able to detect it and load its jQuery plugin?

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.

//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.

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 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM