JavaScript Bundling Issues When Using Unfinished Closures

We all know it’s a good idea to bundle JavaScript files into as few script includes as possible to minimize HTTP request.

And – we all know you should write your code inside closures, to avoid the biggest problem of JavaScript: its dependence on global variables!

But what happens when those two things don’t work together?

For me, they didn’t play nice with each other today. Whenever I bundled my JavaScript files i got an Uncaught TypeError: undefined is not a function.

Consider this code:

/****** a-file.js ******/
!function($) {
  // Code here
}(window.jQuery)

/****** another-file.js ******/
(function ($) {
  $("#hello").text("World!");
})(window.jQuery);​

The error occurred on the first line, inside the closure in another-file.js. Take a look at this jsFiddle.

Since the result of the first closure is true, the above code will evaluate as this:

/****** a-file.js ******/
true

/****** another-file.js ******/
(function ($) {
  $("#hello").text("World!");
})(window.jQuery);​

The only thing missing, is a semicolon to finish off the first closure (updated, and working jsFiddle):

/****** a-file.js ******/
!function($) {
  // Code here
}(window.jQuery);

/****** another-file.js ******/
(function ($) {
  $("#hello").text("World!");   
})(window.jQuery);​

Now, this is a trivial thing to get right, if you were only dealing with your own code base. But with loads of plugins, external libraries and such – you can only pray for the best!

In my case, the script that were causing the error was Twitter Bootstrap scripts. They were all missing the semi-colon in version 2.0, the issue was submitted a month ago, and later fixed