Using Bootstrap 3.0 with Browserify

16,709

Solution 1

This works for me when I'm using bootstrap in browserify:

window.$ = window.jQuery = require('jquery')
var Backbone = require('backbone');
Backbone.$ = $;
require('../../../../bower_components/bootstrap-sass-official/assets/javascripts/bootstrap');

Solution 2

I ran into the same problem: Bootstrap is available in NPM but is not exposed as a Common JS module. The approach I settled on was:

  1. Temporarily set window.$ and window.jQuery
  2. Load Bootstrap.js by requiring it
  3. Revert the value of window.$ and window.jQuery

I placed the code below into a module called bootstrapHack.js and required it at the root of my app before anything else runs.

var jQuery = require('jquery');
window.$ = window.jQuery = jQuery;

require('bootstrap');

jQuery.noConflict(true);

Or if you're only working with one or two Bootstrap components, you can require them individually and cut down on the file size. In this case, just modal and tooltip.

var jQuery = require('jquery');
window.$ = window.jQuery = jQuery;

require('bootstrap/js/tooltip');
require('bootstrap/js/modal');

jQuery.noConflict(true);

Solution 3

A cleaner approach would be to use the atomify plugin. That would help you resolve jQuery, bootstrap.js and bootstrap.css all from npm module.

var gulp = require('gulp');
var atomify = require('atomify');

gulp.task('default', function () {
  atomify.css('less/main.less', 'dist/bundle.css');
  atomify.js('js/index.js', 'dist/bundle.js');
});

You need to @import bootstrap in to your less / css file,

@import 'bootstrap';
@import './other.less';

@dark : #999;

body {
  background-color : @dark;
}

as well as require() bootstrap in your js file,

var $ = jQuery = require('jQuery')
require('bootstrap');
var other = require('./other')

console.log(typeof $().modal);
console.log(other());

module.exports = function() {
  console.log('Executed function xyz');
}

A complete example in this Github repo.

Share:
16,709

Related videos on Youtube

Naresh
Author by

Naresh

Updated on April 19, 2020

Comments

  • Naresh
    Naresh about 4 years

    I am trying to use Bootstrap 3.0 with Browserify 5.9.1, but getting the following error:

    Uncaught ReferenceError: jQuery is not defined
    

    What's the correct way to do this?

    Here are the relavant portions of my package.json:

    {
      ...
      "scripts": {
        "bundle": "browserify main.js -o bundle.js --debug --list"
      },
      "dependencies": {
        "backbone": "~1.1.x",
        "jquery": "~2.1.x",
        "underscore": "~1.6.x"
      },
      "devDependencies": {
        "browserify": "^5.9.1",
        ...
      },
      ...
    }
    

    The module that requires bootstrap is shown below:

    var $ = require('jquery');
    var Backbone = require('backbone');
    Backbone.$ = $;
    require('../../../../bower_components/bootstrap-sass-official/assets/javascripts/bootstrap');
    

    Two things that I don't like here are:

    1. Bootstrap is downloaded using Bower. AFAIK there is no way to get it using npm. This makes the path very long and awkward. Is there a way to make Bootstrap npm friendly?
    2. Bootstrap is not a direct dependency of this module, it is sort of a jQuery plugin. When it is loaded, it simply creates some event handlers on the document to handle events from Bootstarp's widgets. I have to require just so that these event handlers are created. Is this the right way?

    Of course after all this, I still get the "jQuery is not defined" error. I am pulling my hair out trying to get this to work. Please help!

    P.S. Earlier I had the grunt-browserify plugin in the picture and quickly realized that it was using browserify version 4.x with no source map capability. This was making it even harder to debug, so I quickly took it out of the picture and running browserify straight from npm.

    • cvrebert
      cvrebert almost 10 years
      Bootstrap is not written as a CommonJS module. You're going to have to add boilerplate code for that yourself.
    • Jonathan Mast
      Jonathan Mast almost 10 years
      For whatever it is worth, Bootstrap is now available via NPM. This would help out with your first concern re: the unfriendly require path. :)
  • Ziggurat
    Ziggurat over 9 years
    Isn't this solution poluting the global window scope? I think one of the ideas behind browserify (and requirejs) is to keep the global thing at a minimum and only expose the dependencies to those who needs them.
  • mighty007
    mighty007 about 9 years
    Thanks so much! I know what Ziggurat is saying but after screwing with this for days I was finally able to make this work!
  • John
    John about 9 years
    @Ziggurat that's what jQuery does - assigning $ to window
  • Jesse Greathouse
    Jesse Greathouse almost 9 years
    @Ziggaurat yes it is polluting the global window scope. Yes it goes against the concept of commonJS. I wish bootstrap was written as a module, but it's not, and some of us are required use it anyway. Since bootstrap expects jQuery to be in the global scope, there really isn't much we can do as engineers; but as far as hacks go, this one isn't too bad.
  • YPCrumble
    YPCrumble over 8 years
    Is this missing a semicolon after require('jquery')?
  • ooxi
    ooxi almost 8 years
    This should be the accepted answer since the answer by Ian Lim is an ugly hack polluting the global namespace