18

So Bootstrap 4 Beta is out... yey! However Tether has been replaced by Popper.js for tooltip (and other features). I saw an error thrown in the console fast enough to advise me of the change to Popper.js:

Bootstrap dropdown require Popper.js

Seems easy enough, I went and updated my webpack.config.js (the entire config can be seen here) and Bootstrap then started working (the only change I did was to replace Tether with Popper):

plugins: [
new ProvidePlugin({
  'Promise': 'bluebird',
  '$': 'jquery',
  'jQuery': 'jquery',
  'window.jQuery': 'jquery',
  'window.$': 'jquery',
  Popper: 'popper.js' 
}),

I also did the import 'bootstrap' in my main.ts file.

However I now have another problem (which I did not have with Tether), a new error is thrown in the console:

Uncaught TypeError: Popper is not a constructor

If I try to debug in Chrome, I do have Popper loaded as an Object (which is why Bootstrap stopped complaining) as you can see in the print screen below. enter image description here

Finally to include all my code. I use Bootstrap tooltip with a simple custom element built with Aurelia and TypeScript (which used to work with previous Bootstrap alpha 6 and Tether)

import {inject, customAttribute} from 'aurelia-framework';
import * as $ from 'jquery';

@customAttribute('bootstrap-tooltip')
@inject(Element)
export class BootstrapTooltip {
  element: HTMLElement;

  constructor(element: HTMLElement) {
    this.element = element;
  }

  bind() {
    $(this.element).tooltip();
  }

  unbind() {
    $(this.element).tooltip('dispose');
  }
}

Looks like I did not import Popper correctly, if so then what is the best way to achieve that with Webpack 3.x?

ghiscoding
  • 12,308
  • 6
  • 69
  • 112

5 Answers5

35

While browsing Bootstrap 4 documentation. I actually found a section about Webpack which explains how to install it correctly. Following the Bootstrap - installing with Webpack documentation, the answer is to simply modify the webpack.config.js with the following:

plugins: [
  // ...
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    'window.jQuery': 'jquery',
    Popper: ['popper.js', 'default']
  })
  // ...
]

and let's not forget to import it in the main.ts

import 'bootstrap';

and voilà! We are back in business :)

ghiscoding
  • 12,308
  • 6
  • 69
  • 112
  • hey guys! How can i do the same using aurelia.json ? – Jhonatas Kleinkauff Aug 21 '17 at 18:37
  • @JhonatasKleinkauff the question here was for WebPack only, but for `Aurelia-CLI`, have you tried something along the line of the previous Tether import: [aurelia-cli-to-use-with-bootstrap-4](https://stackoverflow.com/questions/39432962/how-to-add-tether-in-aurelia-cli-to-use-with-bootstrap-4/39461325#39461325) – ghiscoding Aug 22 '17 at 13:52
  • @ghiscoding yeah i know, heres what im looking for https://stackoverflow.com/questions/45816118/bootstrap-4-error-bootstrap-dropdown-require-popper-js-with-aurelia-cli-and-r/45816956#comment78591799_45816956 – Jhonatas Kleinkauff Aug 22 '17 at 15:31
  • @JhonatasKleinkauff very similar to previous answer with Tether then, the only difference I see is to use the UMD path. Anyhow, glad you found your answer for the CLI :) – ghiscoding Aug 22 '17 at 15:38
7

If you are using Webpack Do this:

window.$ = window.jQuery = require('jquery');
window.Popper = require('popper.js').default; // pay attention to "default"
require('bootstrap/dist/js/bootstrap');
Amir Hassan Azimi
  • 9,180
  • 5
  • 32
  • 43
6

In bootstrap": "^4.1.1" no need to import jquery and popper.js because those plugins will be already included when 'bootstrap' or bootstrap's plugins imported individually.

Notice that if you chose to import plugins individually, you must also install exports-loader

No need to require files require('exports-loader?file ... '); as mentioned here because this will be taken care automatically by just installing $ npm install exports-loader --save-dev

import 'bootstrap'; // Import all plugins at once

//
// Or, import plugins individually
//
// import 'bootstrap/js/src/alert';
// import 'bootstrap/js/src/button';
// import 'bootstrap/js/src/carousel';
// import 'bootstrap/js/src/collapse';
// import 'bootstrap/js/src/dropdown';
// import 'bootstrap/js/src/modal';
// import 'bootstrap/js/src/popover';
// import 'bootstrap/js/src/scrollspy';
// import 'bootstrap/js/src/tab';
// import 'bootstrap/js/src/tooltip';
// import 'bootstrap/js/src/util';

There is no need to do anything like below:

const webpack = require('webpack');

module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery',
        Popper: ['popper.js', 'default']
      })
    ]
  }
}

I am a vue.js developer and in new vue-cli-3, we create vue.config.js in root and place code like above to register new plugin, but as said there is no need to do all this in bootstrap": "^4.1.1".

Bootstrap's tooltip plugin is depend on popper.js and need to be enabled manually, so you can do like below in the component where you use tooltip element:

<script>
  import $ from 'jquery';

  export default {
    mounted() {
      $('[data-toggle="tooltip"]').tooltip();
    },
  };
</script>
Syed
  • 15,657
  • 13
  • 120
  • 154
3

I just ran into the same issue, and the solution is described here: https://github.com/FezVrasta/popper.js/issues/287

My main.ts now looks like something like the following:

import "jquery";
import Popper from "popper.js";

(<any>window).Popper = Popper;

require("bootstrap");

And I had to run npm install @types/requirejs --save to get the call to require working.

EDIT: I totally missed this the first time around, but the documention actually has a better way to solve this https://getbootstrap.com/docs/4.0/getting-started/webpack/

plugins: [
  ...
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    'window.jQuery': 'jquery',
    Popper: ['popper.js', 'default'],
    // In case you imported plugins individually, you must also require them here:
    Util: "exports-loader?Util!bootstrap/js/dist/util",
    Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown",
    ...
  })
  ...
]
Phil Cox
  • 103
  • 5
  • Your solution wasn't working at first, the biggest reason was that I had to remove Popper completely from the `webpack.config.js`. Can you please mention it in your answer so that I can accept it. – ghiscoding Aug 12 '17 at 15:15
  • Found how to correctly do it directly in the webpack.config, I actually found it by luck while browsing new Bootstrap 4 documentation in their getting started section. So I actually answered my own question but still upvoted yours because that helped me understand the real issue. Thanks again. – ghiscoding Aug 12 '17 at 19:17
0

In ASP.net Core 2 project add the following scripts to of main HTML file ("_Layout.cshtml" file)

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/popper.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>

For me it's working.

HolyM
  • 301
  • 3
  • 9