shakacode/bootstrap-loader

Issue loading popover

borysn opened this issue ยท 23 comments

Hey guys!

I'm running into an issue using popovers, seems they are having trouble. Starting up my application shows an error
Uncaught ReferenceError: Tooltip is not defined popover.js?7071:formatted:93

The referenced line of code in the bootstrap file popover.js shows...

var Default = $.extend({}, Tooltip.Default, {
    ...
});

popovers seem to be working fine in alpha 4, so I'm submitting the issue here. Correct me if I'm mistaken, I could be missing something here.

@borysn can you please help us debug this?

@justin808 I'll see what I can find.

I'm having the exact same issue. @borysn did you find anything?

Util in util.js has the same problem:

Uncaught ReferenceError: Util is not defined _getParentFromElement @ bootstrap.bundle.js:1520

referenced code is in bootstrap file dropdown.js
var selector = Util.getSelectorFromElement(element);

@razagill I tried to do some basic debugging just looking through the code, and poking around breakpoints with my project loaded up. I asked justin about how to debug an npm package properly, and he pointed me to a blog article, but I left off there.

My guess right now is that the loader will struggle with any import statements. popover.js imports Tooltip from tooltip.js, and it's the initialization of Tooltip within popover.js that causes the error. Although I have not seen the error yet, it makes sense that Util would fail too, like @frickt said. Util is imported in most of the javascript files.

I'm going to try and get back to it, but I had a few interviews today, and I'm looking to prepare/move forward with those, so I may not have time.

That is true.
Please compare

The next line

import Tooltip from './tooltip'

is just ignored in dist.

Tow options. Either reference originals or compile into single file as bootstrap did so that all variables available across modules.

why do we use the files in dist and not in src?
We could change createBootstrapRequire.js from ['js', 'dist'] to ['js', 'src']
and the webpack module loader to:

  { test: /bootstrap[\/\\]js[\/\\]src[\/\\]/, loader: 'imports?jQuery=jquery' },

this would work, but i'm not sure if it's the right way...

Is there any workaround, guys?

I can confirm that Utils fails when using only dropdown and itself, I couldn't find a workaround for now.

Bootstrap moved away from UMD in Beta 4 twbs/bootstrap#20072. So the js/dist files will no longer work for the current configuration. This repo will need to use the js/src files like @frickt mentioned and the end user will need to transpile down using Babel.

@borysn @razagill @frickt @Andre-Gl @Andrey-Pavlov @BenjaminSchubert

This works, using bootstrap 4.0.0-alpha.4 and bootstrap-loader 2.0.0-beta.11:

const webpack = require('webpack');

// webpack.config.js
module.exports = {
  /* ... */
  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery",
      Tether: "tether",
      "window.Tether": "tether",
      Tooltip: "exports?Tooltip!bootstrap/js/dist/tooltip",
      Alert: "exports?Alert!bootstrap/js/dist/alert",
      Button: "exports?Button!bootstrap/js/dist/button",
      Carousel: "exports?Carousel!bootstrap/js/dist/carousel",
      Collapse: "exports?Collapse!bootstrap/js/dist/collapse",
      Dropdown: "exports?Dropdown!bootstrap/js/dist/dropdown",
      Modal: "exports?Modal!bootstrap/js/dist/modal",
      Popover: "exports?Popover!bootstrap/js/dist/popover",
      Scrollspy: "exports?Scrollspy!bootstrap/js/dist/scrollspy",
      Tab: "exports?Tab!bootstrap/js/dist/tab",
      Tooltip: "exports?Tooltip!bootstrap/js/dist/tooltip",
      Util: "exports?Util!bootstrap/js/dist/util",
    })
  ]
  /* ... */
};

@frickt You can remove that loader when using the above config.

Make sure to npm install exports-loader --save-dev if you don't have it.

Shame on them for releasing non-modular code in 2016.

Is any PR needed for this issue? I'm glad to merge one in so long as at least one other person besides the PR author vouches for it. I won't have time to look at this for a couple of weeks.

@justin808 I am not familiar enough with webpack loaders to know if it's possible to internalize the exports-loader and ProvidePlugin logic above into bootstrap-loader. It will be a shame if it isn't feasible, since it means additional boilerplate for every user.

Hopefully they just bring back UMD.

At the very least, the readme should be updated with the above information.

Disclaimer: I'm a webpack & bootstrap newb.

After some research, I don't see a way that a loader can add plugins to webpack cleanly. I think the best process may be placing the ProvidePlugin parameter object into a file, which would be included in the bootstrap-loader module. Then the only additional boilerplate would be a single line of code, something like new webpack.ProvidePlugin(require('path/to/file')).

@BenjaminSchubert @frickt For future reference, what's the simplest addition we could make to https://github.com/shakacode/bootstrap-loader/tree/master/examples to test bootstrap interal dependency issues like this one?

@Judahmeek I think what @sky-coding wrote is the simplest way of explaining what to do. I'd add it to the docs with the JQuery path. Having to add manually theses plugins is not a problem given that we also have to add jquery manually.

Ks89 commented

Exactly the same problem.
Bootstrap4 alpha 4 is loaded correctly, but I receive this error into the browser's console:
"Uncaught ReferenceError: Tooltip is not defined"

If necessary, I can add my webpack.config.js

This is my .bootstraprc:

loglevel: debug
bootstrapVersion: 4
useFlexbox: true
styleLoaders:

  • style
  • css
  • postcss
  • sass



    extractStyles: false

    styles:

    mixins: true

    normalize: true

    print: true

    reboot: true

    type: true

    images: true

    code: true

    grid: true

    tables: true

    forms: true

    buttons: true

    animation: true

    dropdown: true

    button-group: true

    input-group: true

    custom-forms: true

    nav: true

    navbar: true

    card: true

    breadcrumb: true

    pagination: true

    jumbotron: true

    alert: true

    progress: true

    media: true

    list-group: true

    responsive-embed: true

    close: true

    tags: true

    modal: true

    tooltip: true

    popover: true

    carousel: true

    utilities: true

    scripts:

    alert: true

    button: true

    carousel: true

    collapse: true

    dropdown: true

    modal: true

    popover: true

    scrollspy: true

    tab: true

    tooltip: true

    util: true

No error while building. Log:

bootstrap-loader: Using config file /Users/MYFOLDER/.bootstraprc
bootstrap-loader: Query from webpack config: none
bootstrap-loader: Using Bootstrap module: bootstrap
bootstrap-loader: Bootstrap module location (abs): /Users/MYFOLDER/node_modules/bootstrap
bootstrap-loader: Bootstrap module location (rel): ../bootstrap
bootstrap-loader: Context: /Users/MYFOLDER/node_modules/bootstrap-loader
bootstrap-loader: Using Bootstrap version: 4
bootstrap-loader: Bootstrap NPM package version: 4.0.0-alpha.4
bootstrap-loader: Normalized params:
{ bootstrapVersion: 4,
loglevel: 'debug',
preBootstrapCustomizations: undefined,
bootstrapCustomizations: undefined,
appStyles: undefined,
useFlexbox: true,
useCustomIconFontPath: undefined,
extractStyles: false,
styleLoaders: [ 'style', 'css', 'postcss', 'sass' ],
styles:
[ 'mixins',
'normalize',
'print',
'reboot',
'type',
'images',
'code',
'grid',
'tables',
'forms',
'buttons',
'animation',
'dropdown',
'button-group',
'input-group',
'custom-forms',
'nav',
'navbar',
'card',
'breadcrumb',
'pagination',
'jumbotron',
'alert',
'progress',
'media',
'list-group',
'responsive-embed',
'close',
'tags',
'modal',
'tooltip',
'popover',
'carousel',
'utilities' ],
scripts:
[ 'alert',
'button',
'carousel',
'collapse',
'dropdown',
'modal',
'popover',
'scrollspy',
'tab',
'tooltip',
'util' ],
configFilePath: '/Users/MYFOLDER/.bootstraprc',
bootstrapPath: '/Users/MYFOLDER/node_modules/bootstrap',
bootstrapRelPath: '../bootstrap' }

module.exports.css = require ("style!css!postcss!resolve-url!sass?sourceMap!./lib/bootstrap.styles.loader.js!./no-op.js");
module.exports.js = require ("./lib/bootstrap.scripts.loader.js!./no-op.js");

50% building modules 425/636 modules 211 active ...de_modules/ng2-validators/src/util.jsbootstrap-loader: Scripts output:
require ("../bootstrap/js/dist/alert");
require ("../bootstrap/js/dist/button");
require ("../bootstrap/js/dist/carousel");
require ("../bootstrap/js/dist/collapse");
require ("../bootstrap/js/dist/dropdown");
require ("../bootstrap/js/dist/modal");
require ("../bootstrap/js/dist/popover");
require ("../bootstrap/js/dist/scrollspy");
require ("../bootstrap/js/dist/tab");
require ("../bootstrap/js/dist/tooltip");
require ("../bootstrap/js/dist/util");

42% building modules 431/804 modules 373 active ...ode_modules/bootstrap-loader/no-op.jsbootstrap-loader: Styles output:
$enable-flex: true;
@import "../bootstrap/scss/_mixins";
@import "../bootstrap/scss/_variables";
@import "../bootstrap/scss/_normalize";
@import "../bootstrap/scss/_print";
@import "../bootstrap/scss/_reboot";
@import "../bootstrap/scss/_type";
@import "../bootstrap/scss/_images";
@import "../bootstrap/scss/_code";
@import "../bootstrap/scss/_grid";
@import "../bootstrap/scss/_tables";
@import "../bootstrap/scss/_forms";
@import "../bootstrap/scss/_buttons";
@import "../bootstrap/scss/_animation";
@import "../bootstrap/scss/_dropdown";
@import "../bootstrap/scss/_button-group";
@import "../bootstrap/scss/_input-group";
@import "../bootstrap/scss/_custom-forms";
@import "../bootstrap/scss/_nav";
@import "../bootstrap/scss/_navbar";
@import "../bootstrap/scss/_card";
@import "../bootstrap/scss/_breadcrumb";
@import "../bootstrap/scss/_pagination";
@import "../bootstrap/scss/_jumbotron";
@import "../bootstrap/scss/_alert";
@import "../bootstrap/scss/_progress";
@import "../bootstrap/scss/_media";
@import "../bootstrap/scss/_list-group";
@import "../bootstrap/scss/_responsive-embed";
@import "../bootstrap/scss/_close";
@import "../bootstrap/scss/_tags";
@import "../bootstrap/scss/_modal";
@import "../bootstrap/scss/_tooltip";
@import "../bootstrap/scss/_popover";
@import "../bootstrap/scss/_carousel";
@import "../bootstrap/scss/_utilities";

20503ms building modules
20ms sealing
1ms optimizing
0ms basic module optimization
42ms module optimization
1ms advanced module optimization
22ms basic chunk optimization
0ms chunk optimization
1ms advanced chunk optimization
0ms module and chunk tree optimization
307ms module reviving
2ms module order optimization
5ms module id optimization
7ms chunk reviving
4ms chunk order optimization
15ms chunk id optimization
796ms hashing
1ms module assets processing
200ms chunk assets processing
49ms additional chunk assets processing
1ms recording
16401ms additional asset processing
160ms chunk asset optimization
2157ms asset optimization
19ms emitting
Hash: 683bbe1d23ba7d0bddf4
Version: webpack 2.1.0-beta.22
Time: 40796ms
Asset Size Chunks Chunk Names
main.3a9fd5dfb81fc10d6971.js 85.2 kB 0 [emitted] main
vendor.a652e2ac43bbbe5f7d20.js 1.53 MB 1 [emitted] vendor
main.3a9fd5dfb81fc10d6971.js.gz 14.8 kB [emitted]
vendor.a652e2ac43bbbe5f7d20.js.gz 340 kB [emitted]
manifest.json 96 bytes [emitted]
index.html 1.89 kB [emitted]
+ 1120 hidden modules

@Ks89 check out the post made a few days ago by @sky-coding, his solution resolves the issue.You can check out my webpack.common.js for a reference.

Ks89 commented

Thank u. It's working.

@borysn Now that the documentation is updated (see above commit), can we close this issue?

@Judahmeek everything looks good to me

@Judahmeek there is a duplicate Tooltip property on my plugins object that made it into the documentation, sorry about that.

@sky-coding @Andrey-Pavlov @Judahmeek we need some agreement on the preferred solution. I'll release once the 3 of you agree, or if we get more consensus from other community participants.

@justin808 I didn't realize there was a disagreement. Using ProvidePlugin or imports-loader is the correct way of consuming a non-modular library, see https://github.com/webpack/docs/wiki/shimming-modules

Their example shows shimming jQuery using ProvidePlugin, implying you wouldn't expect a jQuery plugin/loader to attempt to configure your environment for you. I'd also be okay with bootstrap-loader internally leveraging imports-loader but as mentioned above I don't know if that's technically possible with Webpack.

Compiling from their source should not be an option, if that is the alternative on the table.