bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

Bootstrap 5 not working with Vite and jQuery

Open liamkeily opened this issue 1 year ago • 10 comments

Prerequisites

Describe the issue

Bootstrap 5 provides instructions for getting started with Vite, and separate instructions for optionally using jQuery.

The documentation states

If Bootstrap detects jQuery in the window object it’ll add all of our components in jQuery’s plugin system;

Based on that I am setting window.jQuery in my main.js file, before including a bootstrap plugin.

// Import jQuery
import jQuery from 'jquery';

// Add jQuery to the Window (see https://getbootstrap.com/docs/5.2/getting-started/javascript/#optionally-using-jquery)
window.jQuery = jQuery;

// Import only the Bootstrap components we need
import { Popover } from 'bootstrap';

// Initialise the popover onload
jQuery(function() {
    jQuery('[data-bs-toggle="popover"]').popover();
});

However it does not appear to be correctly registering the plugin.

image

Reduced test cases

This is a fork of the bootstrap example repo, a copy has been made of the vite example and the following commit attempts to make it work with jQuery instead of the Vanilla JS.

https://github.com/liamkeily/bootstrap-examples/pull/1/commits/09fe7f2bbb9d11e68d43ab3c273b7fbc039e3043

What operating system(s) are you seeing the problem on?

macOS

What browser(s) are you seeing the problem on?

Chrome

What version of Bootstrap are you using?

5.3.0

liamkeily avatar Jul 17 '23 13:07 liamkeily

I have dug further into this and it looks like bootstraps defineJQueryPlugin(Popover) and its containing onDOMContentLoaded is getting called before the window.jQuery = jQuery line in main.js. So window.jQuery is not defined at the time it is trying to register the plugin.

I guess this is something to do with the way Vite loads dependencies

liamkeily avatar Jul 17 '23 14:07 liamkeily

This also worked fine for Bootstrap 4, which we are upgrading from.

Created a separate branch on that repo to prove that Bootstrap 4 works https://github.com/liamkeily/bootstrap-examples/compare/vite-and-jquery...liamkeily:bootstrap-examples:vite-and-jquery-bootstrap4

liamkeily avatar Jul 18 '23 09:07 liamkeily

Any PRs that fix the issue are welcome. But please try to add a test case.

XhmikosR avatar Aug 15 '23 11:08 XhmikosR

Any news?

jamesRUS52 avatar Sep 26 '23 11:09 jamesRUS52

I encountered this as well while listening for a Bootstrap modal event - jQuery event wasn't triggered but listening with addEventListener was.

Could Bootstrap expose a function (use() for example, or setJquery()) which would let us set the jQuery library for Bootstrap to use, falling back to the window.jQuery if not present?

Then the usage would be:

import $ from 'jquery';
import bootstrap from 'bootstrap';

bootstrap.use($);

instead of doing window.jQuery = $;?

I can create a PR if this might be of interest?

AllanJard avatar Jan 23 '24 12:01 AllanJard

This is actually really easy to fix, it's just not documented anywhere.

Create a "wrapper" for jquery like this:

jquery_import.js

import $ from 'jquery';
window.$ = window.jQuery = $;

In your main js file, import this wrapper before importing the JS for bootstrap 5.

If you don't use a wrapper file, Vite moves the global declaration to the very end of the built JS file, and it won't work.

skeets23 avatar May 13 '24 16:05 skeets23

Thanks @skeets23 that did actually work

liamkeily avatar Jun 17 '24 13:06 liamkeily

Let's reopen the issue and wait for someone to submit a PR. I'm pretty sure it's a common issue worth documenting.

XhmikosR avatar Jun 18 '24 05:06 XhmikosR