RequireJS + Backbone without jQuery? - javascript

I'm trying to use RequireJS, here is my config file :
require.config({
baseUrl: "/scripts",
paths: {
zepto: "zepto.min",
underscore: "underscore.min",
backbone: "backbone.min"
},
shim: {
zepto: {
exports: "$"
},
underscore: {
exports: "_"
},
backbone: {
deps: ["underscore", "zepto"],
exports: "Backbone"
}
}
});
And this is my app.js :
require(['backbone'], function(Backbone) {
console.log('loaded!');
});
This works fine, but I don't know why RequireJS is trying to load jQuery.

Because Backbone requires module called jquery (look at top of backbone.js) file.
// Set up Backbone appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
// Export global even in AMD case in case this script is loaded with
// others that may still expect a global Backbone.
root.Backbone = factory(root, exports, _, $);
});
and You haven't defined this module.
To hack this use zepto as jquery:
require.config({
baseUrl: "/scripts",
paths: {
jquery: "zepto.min",
underscore: "underscore.min",
backbone: "backbone.min"
},
shim: {
jquery: {
exports: "$"
},
underscore: {
exports: "_"
}
}
});
And second: shim only works with non-amd modules. Backbone is AMD module.

Related

require.js shim for lib jquery, marionette, backbone, underscore

I used to link libraries :
shim: {
backbone: {
deps: ["jquery", "underscore"],
exports: "Backbone"
},
marionette: {
deps: ["backbone"],
exports: "Marionette"
},
angular: {
exports: "angular"
}
}
but now I have read that these libs uses AMD and shim property is not required! Is it?
main.js
paths: {
marionette: "backbone.marionette"
}
some.js
define( "util",
['marionette'],
function(Marionette){
//test arguments!
//console.log($)
//console.log(jQuery)
//console.log(Backbone)
//console.log(_)
console.log(Marionette) //exist!
}
);
If the third party scripts are not AMD compatible you have to use shims.
You might check if the scripts are AMD compatible if at the top the code does have something like this:
(function(root, factory) {
// Set up Backbone appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
// Export global even in AMD case in case this script is loaded with
// others that may still expect a global Backbone.
root.Backbone = factory(root, exports, _, $);
});
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore'), $;
try { $ = require('jquery'); } catch(e) {}
factory(root, exports, _, $);
// Finally, as a browser global.
} else {
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
}
}(this, function(root, Backbone, _, $) {
// ....
}
And here is how look like for example the configuration file on one of my project:
shim: {
// jQuery Mobile
"jquerymobile": ["jquery"],
// Twitter Bootstrap jQuery plugins
"bootstrap": ["jquery"],
// jQueryUI
"jqueryui": ["jquery"],
// jQuery Cookie
"jquery.cookie": {
deps: ["jquery"],
exports: "jquery.cookie"
},
// jQuery easing functions
"jquery.easing" : {
deps: ["jquery"],
exports: "jquery.easing"
},
// Shim backbone to resolve conflicts on minification
"backbone": {
deps: ['underscore', 'jquery'],
init: function(_, $) {
return this.Backbone = Backbone.noConflict();
}
},
// Backbone.validateAll plugin that depends on Backbone
"backbone.validateAll": ["backbone"],
"backbone.paginator" : {
deps: ["backbone"],
exports : "Backbone.Paginator"
},
"backgrid" : {
deps : ['jquery', 'underscore', 'backbone'],
exports: "Backgrid"
},
"backgrid.paginator" : {
deps: ["backbone", "backgrid"],
exports : "Backgrid.Paginator"
}
}

Separate scripts with RequireJS

I recently worked on a web app, and i wanted to separate it into modules.
I searched and found out that RequireJs is the best for this. I read the doc, and some tutorials about it and came up with this
requirejs.config({
baseUrl: "js/lib",
shim: {
'jquery-1.12.1.min': ['jquery-1.12.1.min'],
'materialize.min': ['materialize.min'],
'knockout-3.4.0': ['knockout-3.4.0'],
'pouchdb-5.3.0.min': ['pouchdb-5.3.0.min']
},
waitSeconds: 0,
paths: {
'jquery-1.12.1.min': 'jquery-1.12.1.min',
'materialize.min': 'materialize.min',
'knockout-3.4.0': 'knockout-3.4.0',
'pouchdb-5.3.0.min': 'pouchdb-5.3.0.min',
}
});
require(["jquery-1.12.1.min", "knockout-3.4.0", "materialize.min", "pouchdb-5.3.0.min"], function($, ko) { //My main functions and other stuff ... }
My index has the following:
<script data-main="js/main" src="js/lib/require.js"></script>
<script type="text/javascript" src="js/converter.js"></script>
But it seems that my Jquery, KO, materialize.css and pouchdb aren't loading as i see on my chrome dev tools in Network:
I also read about the shim config how to set up the dependences and i want them in that order. I don't really know what am i missing, any help would really be appreciated.
Folder structure is:
js:
lib:
->jquery-1.12.1.min.js
->knockout-3.4.0.js
->pouchdb-5.3.0.min.js
->materialize.min.js
->require.js
main.js
converter.js
Ok it seems require and materialze.css have a problem with hammer.js, what i recommend is you go and download Hammer.min.js and include it in your lib folder.
Then in your main.js add the following:
requirejs.config({
baseUrl: 'js/lib',
waitSeconds: 0,
paths: {
app: '../app',
jquery: 'jquery-1.12.1.min',
materialize: 'materialize.min',
knockout: 'knockout-3.4.0',
pouchdb: 'pouchdb-5.3.0.min',
hammer: 'hammer.min'
},
shim: {
hammer: {
deps: ['jquery']
},
pouchdb: {
deps: ['jquery']
},
knockout: {
deps: ['jquery'],
exports: 'ko'
},
materialize: {
deps: ['jquery', 'hammer'],
},
jquery: {
exports: '$'
}
}
});
You include you hammer and also the dependency for jquery on it. And i see that you didn't put the PouchDb object in the function:
define(["jquery", "knockout", "pouchdb", "materialize" ], function($, ko, PouchDB) {...
Hope this helps
Using path, requirejs replace module id prefixes (name in config) with the corresponding value.
Using shim you can export a global variable and configure the dependencies ( materialize depends jquery so you have to import jQuery before importing materialize.js )
requirejs.config({
baseUrl: "js/lib",
waitSeconds: 0,
paths: {
'jquery': 'jquery-1.12.1.min',
'materialize': 'materialize.min',
'knockout': 'knockout-3.4.0',
'pouchdb': 'pouchdb-5.3.0.min',
'hammer': 'hammer.min',
},
shim: {
pouchdb: {
deps: ['jquery']
},
knockout: {
exports: 'ko'
},
materialize: {
deps: ['jquery', 'hammer']
},
jquery: {
exports: '$'
}
}
});
require(["jquery", "knockout", "materialize", "pouchdb"], function ($, ko) {
console.log($);
console.log(ko);
});

Backbone.js not working with Require.js bundle

I can't get Backbone.js to play nicely with require.js' bundle system.
This works:
requirejs.config({
baseUrl: 'assets/',
bundles: {
corejs: ['jquery', 'underscore']
},
paths: {
corejs: '../core',
jquery: '../static/js/jquery',
backbone: '../static/js/backbone',
underscore: '../static/js/underscore',
knockout: '../static/js/knockout',
knockback: '../static/js/knockback'
},
shim: {
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
},
deps: ['corejs']
});
require(['app/app'], function(App) {
App.initialize();
});
Changing bundles to be
bundles: {
corejs: ['jquery', 'underscore', 'backbone']
}
results in a require.js timeout
core.js currently consists of concatted jQuery, Underscore, Backbone
Backbone is available on the browser console, even before the timeout.
As #ivarni mentioned in the comments, Backboone has had CommonJS support added:
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore'), $;
try { $ = require('jquery'); } catch(e) {}
factory(root, exports, _, $);
which means that if you use a recent version of Backbone you can just require it normally without having to create a shim.

Require.js/Jquery Datable : undefined is not a function

I am trying to load JQuery datatables with Require.js
This is my JS module where I would like to use datatables :
define([
"jquery",
"text!orders_list.tpl",
"dataTables"
], function($, OrdersListTemplate, dataTables)
{
console.log($);
console.log($.fn.dataTable);
... more logic after
How I call my JS module in HTML :
require(['./js/config'], function (common)
{
require(
[
'js/modules/init',
...
'js/modules/orders_list.js'
],
function (init, ..., orders_list)
{
init.initialize();
...
orders_list.initialize();
});
});
How I have defined my config :
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
...
},
paths: {
jquery: '../../shops_common/js/lib/jquery-1.9.1',
backbone: '../../shops_common/js/lib/backbone.min',
underscore: '../../shops_common/js/lib/underscore.min',
dataTables: 'http://datatables.net/download/build/nightly/jquery.dataTables'
},
waitSeconds: 300
});
But $.fn.dataTable is always undefined...
Any idea why?
Thanks.
I found the solution after extensive research: Datatables is a named module you must use the name "datatables" in your require

Underscore.string with RequireJS

I'm trying to use both Underscore and Underscore.string with RequireJS.
Contents of main.js:
require.config({
paths: {
'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min',
'underscore-string': '//cdnjs.cloudflare.com/ajax/libs/underscore.string/2.3.0/underscore.string.min',
},
shim: {
'underscore': {
exports: '_'
},
'underscore-string': {
deps: ['underscore'],
exports: '_s'
},
}
});
var modules = ['underscore-string'];
require(modules, function() {
// --
});
Browser sees the _, but doesn't see the _s - it is undefined.
Ideally i want to have Underscore under _ and Underscore.string under _.str, but _ and _s are fine too. How can i do that?
Versions: RequireJS 2.1.5, Underscore 1.4.4, Underscore.string 2.3.0
Note: Thanks to #jgillich make sure, that paths have two slashes (//cdnjs.cloudfare.com/...), otherwise the browser would think that URL is relative to the server, and Firebug will throw:
Error: Script error
http://requirejs.org/docs/errors.html#scripterror
I found the error. For some reason RequireJS doesn't work with version of Underscore.string from cdnjs.com, so i replaced it with Github version. I guess it has something to do with the commit 9df4736.
Currently my code looks like the following:
require.config({
paths: {
'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min',
'underscore-string': '//raw.github.com/epeli/underscore.string/master/dist/underscore.string.min',
},
shim: {
'underscore': {
exports: '_'
},
'underscore-string': {
deps: ['underscore'],
},
}
});
var modules = ['underscore', 'underscore-string'];
require(modules, function(_) {
// --
});
Underscore.string resides in _.str.
Edit: As of 16 July 2013 the CDNJS version is updated with the upstream.
Battling with this for hours before i understand what i was doing wrong
This is what i did wrong
You should not rename the file underscore.string in main.js
even though in my library i did rename the file in paths i name it back to 'underscore.string'
This is how your main.js should look like
require.config({
paths: {
underscore: 'lib/underscore',
'underscore.string' : 'lib/_string' ,
},
shim: {
underscore: {
exports: '_',
deps: [ 'jquery', 'jqueryui' ]
},
'underscore.string': {
deps: [ 'underscore' ]
},
}
....
You could then either add it as dependency with in your shim like i did for my mixin file
shim: {
mixin : {
deps: [ 'jquery', 'underscore', 'underscore.string' , 'bootstrap' ]
},
Or just define it in your different pages like
/*global define */
define([
'underscore.string'
], function ( ) {
it just work now you can access it through _.str or _.string
This is why you should do it this way and not try to name it something else
on line 663 of underscore.string.js
// Register as a named module with AMD.
if (typeof define === 'function' && define.amd)
define('underscore.string', [], function(){ return _s; });
Which means that it will only register it with AMD require JS if you are defining 'underscore.string'
works for my ONLY if I use exact "underscore.string" module name in shim. Seems related to hardcoded name in underscore.string itself
Exempt from underscore.string source code (this branch is executed when require used):
// Register as a named module with AMD.
if (typeof define === 'function' && define.amd)
define('underscore.string', [], function(){ return _s; });
So for me the only working configuration is:
require.config({
paths: {
'underscore': '//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min',
'underscore.string': '//raw.github.com/epeli/underscore.string/master/dist/underscore.string.min',
},
shim: {
'underscore': {
exports: '_'
},
'underscore.string': {
deps: ['underscore'],
},
}
});
var modules = ['underscore', 'underscore.string'];
require(modules, function(_) {
// --
});
Here's a working code using Requirejs "order" plugin, also includes Jquery, and everything loads without any conflict:
requirejs.config({
baseUrl: "assets",
paths: {
order: '//requirejs.org/docs/release/1.0.5/minified/order',
jquery: 'http://code.jquery.com/jquery-2.1.0.min',
underscore: '//underscorejs.org/underscore-min',
underscorestring: '//raw.githubusercontent.com/epeli/underscore.string/master/dist/underscore.string.min',
underscoremixed: 'js/underscore.mixed' // Create separate file
},
shim: {
underscore: { exports: '_' },
underscorestring: { deps: ['underscore'] }
}
});
require(['order!jquery','order!underscoremixed'], function($,_) {
// test
console.log( _.capitalize('capitalized text') );
});
Inside js/underscore.mixed.js put the following...
define(['underscore','underscorestring'], function() {
_.mixin(_.str.exports());
return _;
});
Cheers! :)

Categories