Kenshirou's avatar

Integrating Bootstrap 4 beta

I have spent hours to integrate bootstrap 4 beta but still have issues with popper.js. Anyone has been sucessfull in this matter? Popper is installed because it appears under node_modules. But I am missing something because google console keep saying popper is required. Please help.

0 likes
7 replies
Kenshirou's avatar

Thanks everyone for all suggested solution. But it still doesn't work. I keep receiving same message from google console:

Uncaught Error: Bootstrap dropdown require Popper.js (https://popper.js.org)
    at app.js?id=fa54c74b7c02e3e6ddba:sourcemap:5494
    at app.js?id=fa54c74b7c02e3e6ddba:sourcemap:5494
    at Object.<anonymous> (app.js?id=fa54c74b7c02e3e6ddba:sourcemap:5494)
    at Object../node_modules/bootstrap/dist/js/bootstrap.min.js (app.js?id=fa54c74b7c02e3e6ddba:sourcemap:5495)
    at __webpack_require__ (app.js?id=fa54c74b7c02e3e6ddba:sourcemap:20)
    at Object.0 (app.js?id=fa54c74b7c02e3e6ddba:sourcemap:45976)
    at __webpack_require__ (app.js?id=fa54c74b7c02e3e6ddba:sourcemap:20)
    at app.js?id=fa54c74b7c02e3e6ddba:sourcemap:63
    at app.js?id=fa54c74b7c02e3e6ddba:sourcemap:66

Below is what I've done so far. Please, help.

After running npm install [email protected] --save:

package.json:

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },
  "devDependencies": {
    "axios": "^0.16.2",
    "bootstrap": "^4.0.0-beta",
    "cross-env": "^5.0.1",
    "jquery": "^3.1.1",
    "laravel-mix": "^1.0",
    "lodash": "^4.17.4",
    "vue": "^2.1.10"
  },
  "dependencies": {
    "popper.js": "^1.11.0"
  }
}

resources/assets/sass/app.scss:

// Fonts
@import url("https://fonts.googleapis.com/css?family=Raleway:100,600");

// Variables
// @import "variables";

// Bootstrap

@import "node_modules/bootstrap/scss/bootstrap";

resources/assets/js/bootstrap.js:

window._ = require('lodash');

try {
    window.$ = window.jQuery = require('jquery');
    window.Popper = require('popper.js').default;
    require('bootstrap');
} catch (e) {}

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

webpack.mix.js:

mix.autoload({
    jquery: ['$', 'window.jQuery', 'jQuery'],
    popper: ['popper.js']
})

   .js([
    'node_modules/jquery/dist/jquery.slim.min.js',
    'node_modules/popper.js/dist/umd/popper.min.js',
    'node_modules/bootstrap/dist/js/bootstrap.min.js',
    'resources/assets/js/app.js'], 'public/js/app.js')

   .sass('resources/assets/sass/app.scss', 'public/css')
   .sass('resources/assets/sass/welcome.scss', 'public/css')

   .version();

welcome.blade.php:

 <!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel</title>

    <link rel="stylesheet" href="{{ mix('/css/app.css') }}">
    <link rel="stylesheet" href="{{ mix('/css/welcome.css') }}">
      
  </head>
  <body>
    <div class="flex-center position-ref full-height">
      @if (Route::has('login'))
          <div class="top-right links">
              @auth
                  <a href="{{ url('/home') }}">Home</a>
              @else
                  <a href="{{ route('login') }}">Login</a>
                  <a href="{{ route('register') }}">Register</a>
              @endauth
          </div>
      @endif

      <div class="content">
          <div class="title m-b-md">
              Laravel
          </div>

          <div class="links">
            <a href="https://laravel.com/docs">Documentation</a>
            <a href="https://laracasts.com">Laracasts</a>
            <a href="https://laravel-news.com">News</a>
            <a href="https://forge.laravel.com">Forge</a>
            <a href="https://github.com/laravel/laravel">GitHub</a>
          </div>
      </div>
    </div>

    <script src="{{ mix('/js/app.js') }}"></script>
  </body>
</html>
1 like
Kenshirou's avatar
Kenshirou
OP
Best Answer
Level 7

The laidbackwebsage answer to the discussion Laravel Mix Issue proved to be quite useful.

By replacing resources/assets/js/bootstrap.js with:

import Popper from 'popper.js/dist/umd/popper.js';

window._ = require('lodash');

try {
    window.$ = window.jQuery = require('jquery');
    window.Popper = Popper;
    require('bootstrap');
} catch (e) {}

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

and webpack.mix.js with:

mix.autoload({
    jquery: ['$', 'window.jQuery', 'jQuery'],
    'popper.js/dist/umd/popper.js': ['Popper']
})

   .js([
    'node_modules/jquery/dist/jquery.slim.min.js',
    'node_modules/popper.js/dist/umd/popper.min.js',
    'node_modules/bootstrap/dist/js/bootstrap.min.js',
    'resources/assets/js/app.js'], 'public/js/app.js')

   .sass('resources/assets/sass/app.scss', 'public/css')
   .sass('resources/assets/sass/welcome.scss', 'public/css')

   .version();

After those changes all errors from google console are gone.

1 like
rawfan's avatar

@Kenshirou Actually this looks like a mixture of all solution by @laidbackwebsage with duplication and multiple loading of libraries that are already loaded.

1 like
ovvessem's avatar

Agreeing with @rawfan. Yes it works but with this 'solution' you will load the same libraries (jquery, popper and bootstrap) multiple times which leads to unnessecary overhead.

No need for the autoload definition and changes to .js() in webpack.min.js.

rawfan's avatar

@ovvessem for me it doesn't seem to work without the autoload definition, though. How are you doing it?

Please or to participate in this conversation.