Unable to load jQuery plugins when using requirejs & r.js optimizer

amd, coffeescript, javascript, requirejs

Solution

I encountered the same issue. I think the reason this error occurs is because `DT_bootstrap.js` is not a AMD module while it depends on the side effects of one. In this case `jquery.dataTables.js`.

When RequireJS optimizer combines all the modules you reference into one big JS file, the raw `DT_bootstrap.js` is somewhere in the middle of it, some place after `jquery.dataTables.js`. The problem is that `DT_bootstrap.js` is evaluated immediately when your combined js file is loaded. It wants `$.fn.dataTable` to be defined when it encounters the line:

$.extend( true, $.fn.dataTable.defaults, {

Since `jquery.dataTables.js` is a AMD module it has been compiled but not evaluated yet. Only in later code where it is required as a dependency will it be evaluated, and only then will it define `$.fn.dataTable`.

I worked around this by wrapping 'DT_bootstrap.js' in a AMD module definition, like is done here: https://github.com/amdjs/backbone/blob/master/backbone.js#L8-L24

For example:

(function(root, factory) {
  // Set up DT_bootstrap appropriately for the environment.
  if (typeof define === 'function' && define.amd) {
    // AMD
    define(['jquery', 'datatables', 'bootstrap'], function($) {
      factory($);
    });
  } else {
    // Browser globals
    factory(root.jQuery);
  }
}(this, function($) {
    // <--- original DT_bootstrap.js goes here 
}));

It solved the issue for me.

Problem

I'm having a bit of trouble with my the requirejs optimizer. After I run the optimizer, I get a few error messages in my build/compiled file. When running my web application without the optimize step I do not have any errors. This is my client.js file (contains config) (coffeescript) ``` requirejs.config baseUrl: '/source/' paths: text: 'lib/text' io: 'lib/socket.io' underscore: 'lib/underscore' backbone: 'lib/backbone' jquery: 'lib/jquery' # almond: 'lib/almond' bootstrap: 'lib/bootstrap' bootstrapFileUpload: 'lib/bootstrap-fileupload' jqueryUniform: 'lib/jquery.uniform' jqueryBrowser: 'lib/jquery.browser' datatables: 'lib/jquery.dataTables' datatables_bootstrap: 'lib/DT_bootstrap' shim: io: exports: 'io' jquery: exports: 'jQuery' jqueryBrowser: deps: ['jquery'] jqueryUniform: deps: ['jqueryBrowser', 'jquery'] underscore: exports: '_' backbone: deps: ['underscore', 'jquery'] exports: 'Backbone' datatables_bootstrap: deps: ['jquery', 'datatables'] datatables: deps: ['jquery'] require ['routers/router', 'backbone'], (Router, Backbone) -> MainRouter = new Router() Backbone.history.start() ``` And here is my config for the optimizer. I run the optimizer from nodejs after requiring 'requirejs' as a module. ``` config = baseUrl: __dirname + '/../client/source' name: 'lib/almond' include: './client' optimize: 'none' out: __dirname + '/../client/' + hash + '.js' paths: text: 'lib/text' io: 'lib/socket.io' underscore: 'lib/underscore' backbone: 'lib/backbone' jquery: 'lib/jquery' bootstrap: 'lib/bootstrap' bootstrapFileUpload: 'lib/bootstrap-fileupload' jqueryUniform: 'lib/jquery.uniform' jqueryBrowser: 'lib/jquery.browser' datatables: 'lib/jquery.dataTables' datatables_bootstrap: 'lib/DT_bootstrap' shim: bootstrap: exports: 'bootstrap' bootstrapFileUpload: exports: 'bootstrapUpload' io: exports: 'io' jquery: exports: 'jQuery' jqueryBrowser: deps: ['jquery'] jqueryUniform: deps: ['jqueryBrowser', 'jquery'] underscore: exports: '_' backbone: deps: ['underscore', 'jquery'] exports: 'Backbone' datatables: deps: ['jquery'] datatables_bootstrap: deps: ['jquery', 'datatables'] requirejs.optimize config, (buildResponse) -> js = true if js && css require './server' , (err) -> console.log 'requirejs err' console.log err ``` The specific error I'm seeing in chrome is: "Uncaught TypeError: Cannot read property 'defaults' of undefined" Which correlates to this snippet: ``` /* Set the defaults for DataTables initialisation */ $.extend( true, $.fn.dataTable.defaults, { ``` Any idea what might be going wrong? Thanks!

Original source