Require.js + SignalR - requirejs

I have been working with Require.JS and SignalR over the past few days and I noticed that when I load my site sometimes the SignalR/Hubs seems to get loaded before jquery despite my require.js configuration appearing to be correct.
Here's my config:
require.config({
paths: {
jQuery: 'libs/jquery/jquery',
Underscore: 'libs/underscore/underscore',
Backbone: 'libs/backbone/backbone',
Marionette: 'libs/backbone/backbone.marionette'
}
});
require([
'app',
'order!libs/jquery/jquery-min',
'order!libs/jQueryUI/jquery-ui-1.8.11.min',
'order!libs/jqGrid/grid.locale-en',
'order!libs/jqGrid/jquery.jqGrid.min',
'order!libs/underscore/underscore-min',
'order!libs/backbone/backbone-min',
'order!Marionette',
'order!libs/jquery.signalR-0.5.1',
'order!noext!signalr/hubs'
], function (app) {
app.initialize();
});
When this fails I get an error on line 16 of the hubs file. It says uncaught TypeError: Cannot read property 'signalR' of undefined.
Upgraded to V2 and modified my config.
var fRequire = require.config({
paths: {
jQuery: 'libs/jquery/jquery',
Underscore: 'libs/underscore/underscore',
Backbone: 'libs/backbone/backbone',
Marionette: 'libs/backbone/backbone.marionette',
sigr: 'libs/jquery.signalR-0.5.1'
},
shims: {
"libs/jquery.signalR-0.5.1": {
deps: ["jQuery"]
},
"libs/jqGrid/jquery.jqGrid.min": {
deps: ["jQuery"]
},
"libs/jquery/jquery-ui-1.8.19.min": {
deps: ["jQuery"]
},
"libs/jqGrid/grid.locale-en": {
deps: ["jQuery"]
},
"noext!signalr/hubs": {
deps: ["sigr"]
}
}
});
fRequire([
'app'
], function (app) {
app.initialize();
});
Now require is looking in the wrong locations for jquery, underscore, etc...despite my telling it specifically where to look. Perhaps this has something to do with me following an old tutorial when I configured require using v1.
http://backbonetutorials.com/organizing-backbone-using-modules/
FINAL UPDATE:
Here is my working config. Hopefully it'll help any newbies like myself get passed this issue.
require.config({
baseUrl: '/js',
paths: {
"jquery": 'libs/jquery/jquery-min',
"underscore": 'libs/underscore/underscore-min',
"backbone": 'libs/backbone/backbone-min',
"marionette": 'libs/backbone/backbone.marionette',
"sigr": 'libs/jquery.signalR-0.5.1'
},
shims: {
"backbone": {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
"underscore": {
deps: ["jquery"]
},
"marionette": {
deps: ["backbone", "jquery"]
},
"sigr": {
deps: ["jquery"]
},
"libs/jqGrid/jquery.jqGrid.min": {
deps: ["jquery"]
},
"libs/jquery/jquery-ui-1.8.19.min": {
deps: ["jquery"]
},
"libs/jqGrid/grid.locale-en": {
deps: ["jquery"]
},
"noext!signalr/hubs": {
deps: ["sigr"]
}
}
});
// for future ref, I loaded jquery here because app.js references sigr which requires it.
// without enabling it before the module is loaded sigr would complain jquery was not enabled.
require([
'libs/domReady',
'app',
'jquery'
], function (domReady, app, $) {
domReady(function () {
app.initialize();
});
});
It was mandatory that I load jquery in the function(domready, app, $). Failing to do so will result in signalr reporting that it cannot be found.

If you're using requirejs 2.x you can use the "shims" config attribute. There you can specify the dependencies between files that are not AMD compliant, like jquery, jqueryui, etc..
Using your configuration as example:
require.config({
paths: {
jQuery: 'libs/jquery/jquery',
Underscore: 'libs/underscore/underscore',
Backbone: 'libs/backbone/backbone',
Marionette: 'libs/backbone/backbone.marionette'
},
// specify depedencies
shim: {
"libs/jquery.signalR-0.5.1" : {
deps: ["jQuery"]
},
"libs/jqGrid/jquery.jqGrid.min" : {
deps: ["jQuery"]
}
}
});
Also, configure the dependencies in "shims" eliminates the use of the "order!" plugin.
Tip: Use "paths" to set a friendly name for apis that your system use, so when a new version of that api is released you can just change in "paths" and you're done.

Just to follow up on the answer provided and why you are still having to pre-include jQuery... the config setting for require is "shim", not "shims". Require won't recognize and preload the dependencies specified without the correct spelling of the config setting. I got hammered by this recently and posted about it: http://mikeycooper.blogspot.com/2013/01/requirejs-20-dependencies-seemingly.html

Related

"define is not defined" - jasmine-node requirejs in Nodejs

I am trying to run jasmine tests on files that are using requirejs. I have a require.config.js file which provides all the configuration for the requirejs and I am passing to this command to run the jasmine test.
jasmine-node --runWithRequireJs --captureExceptions --requireJsSetup spec/require.config.js spec/modules/test.spec.js
My require.config.js looks like this -
var require = {
baseUrl: "../app",
urlArgs: 'cb=' + Math.random(),
paths: {
jquery: '../assets/js/libs/jquery-1.8.2',
underscore: '../assets/js/libs/underscore-min',
backbone: '../assets/js/libs/backbone-min',
jasmine: '../spec/lib/jasmine',
jasminehtml: '../spec/lib/jasmine-html',
boot: '../spec/lib/boot',
spec: '../spec/',
handlebars : '../assets/js/libs/handlebars-1.0.0.beta.6',
// plugins
jqueryui : '../assets/js/plugins/jquery-ui',
jqgrid : '../assets/js/plugins/jqGrid',
jqgridlocale : '../assets/js/plugins/i18n/grid.locale-en',
jqform : '../assets/js/plugins/jquery.form',
jqfiledownload : '../assets/js/plugins/jquery.fileDownload',
migrate: '../assets/js/plugins/jquery-migrate',
text : '../assets/js/plugins/text'
},
shim: {
'underscore': {
exports: "_"
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'jasmine': {
exports: 'jasmine'
},
'jasminehtml': {
deps: ['jasmine'],
exports: 'jasmine'
},
'boot': {
deps: ['jasmine', 'jasminehtml'],
exports: 'window.jasmineRequire'
},
'handlebars' : {
exports : 'Handlebars'
},
'text' : {
exports : 'text'
},
'jqueryui' : [ 'jquery' ],
'jqgrid' : [ 'jquery' ],
'jqgridlocale' : [ 'jquery' ],
'jqform':['jquery'],
'jqfiledownload':['jquery'],
'migrate':['jquery']
}};
And my test.spec.js file looks like this -
define(['modules/models/RouteModel','modules/models/RestWebService'], function(RouteModel,RestWebService){
describe("RouteModel :", function(){
it("should create an test instance", function(){
expect(RouteModel).not.toBe(null);
});
});
After running the command I am getting in the console
ReferenceError: define is not defined at C:\Users\TestProject\spec\modules\test.spec.js:1:1
What can be the problem in this case? Is this a path configuration issue?
P.S. - I want complete console output of jasmine, not browser output in jasmine.
Error is pretty much straight forward you need to load requirejs before calling it's function. you can find more clear idea from below link:
https://stackoverflow.com/a/29317859/1607130

Why my r.js won't include the 3rd parties js files when generating one? How to include them?

I'm using requirejs in my web app, and have several 3rd party libraries(e.g. jquery, underscore), and my own js files.
Here is the "main.js" which will be loaded by requirejs:
require.config({
baseUrl: 'public/js',
paths: {
jquery: '../vendor/jquery/jquery',
underscore: '../vendor/underscore/underscore',
modernizr: '../vendor/modernizr/modernizr'
},
shim: {
underscore: {
exports: "_"
},
modernizr: {
exports: "Modernizr"
}
}
});
require(['app']);
And here is my grunt config:
requirejs: {
compileJs: {
options: {
baseUrl: "src/main/resources/public/js",
mainConfigFile: "src/main/resources/public/js/main.js",
dir: "src/main/resources/public/min/js",
optimize: "uglify2",
removeCombined: true,
generateSourceMaps: true,
modules: [
{
name: "main"
}
]
}
}
}
grunt.loadNpmTasks('grunt-contrib-requirejs');
When I run the task, it will generate a minified "main.js" which contains all my own code. But I also want it to contain the 3rd libraries(jquery, underscore, modernizr).
I tried again and again, but never succeed, nor find the reason. Why and how to include them?

How to optimize large js app with r.js optimizer + load libs like jquery, bootstrap from a CDN?

We have built a huge backbone-marionette application with a lot of different libraries (bootstrap, gmaps, momentjs etc.). Everything works like charm when I combine everything into a single even in production mode. To improve the performance most of the libraries should be loaded from a CDN now.
But this seems not be as easy as expected. I started with this great tutorial (http://tech.pro/blog/1639/using-rjs-to-optimize-your-requirejs-project) and added a infrastructure module which is responsible to load the external libs.
infrastructure.js
define([
'jquery'
], function($) {
'use strict';
});
main.js (it has grown in the last few months a bit :D)
require.config({
urlArgs: 'bust=1386581060770',
paths: {
// jquery: '../../bower_components/jquery/dist/jquery',
jquery: '//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min',
underscore: '../../bower_components/underscore/underscore',
marionette: '../../bower_components/marionette/lib/backbone.marionette',
backbone: '../../bower_components/backbone/backbone',
moment: '../../bower_components/moment/moment',
'moment.de': '../../bower_components/moment/lang/de',
text: '../../bower_components/text/text',
'backbone.modelbinder': '../../bower_components/backbone.modelbinder/Backbone.ModelBinder',
'backbone.analytics': '../../bower_components/backbone.analytics/backbone.analytics',
'requirejs-i18n': '../../bower_components/requirejs-i18n/i18n',
'jquery.cookie': '../../bower_components/jquery.cookie/jquery.cookie',
'jquery.simplePagination': '../../bower_components/jquery.simplePagination/jquery.simplePagination',
'underscore.string': '../../bower_components/underscore.string/dist/underscore.string.min',
parsleyjs: '../../bower_components/parsleyjs/dist/parsley',
'parsleyjs-de': '../../bower_components/parsleyjs/src/i18n/de',
'parsleyjs-comparison': '../../bower_components/parsleyjs/src/extra/validator/comparison',
requirejs: '../../bower_components/requirejs/require',
'underscore.deepExtend': '../../vendor/others/tools/underscore.mixin.deepExtend',
'underscore.templatehelper': '../../vendor/others/tools/underscore.mixin.templateHelper',
templates: '../templates',
infrastructure: 'infrastructure',
confighandler: 'config/confighandler',
layout: 'views/layout',
general: 'general',
helper: 'helper',
vent: 'vent',
view: 'views',
model: 'models',
module: 'modules',
behaviors: 'behaviors',
collection: 'collections',
controller: 'controllers',
nls: 'nls',
'bootstrap-select': '../../bower_components/bootstrap-select/bootstrap-select',
'eonasdan-bootstrap-datetimepicker': '../../bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
'eonasdan-bootstrap-datetimepicker.de': '../../bower_components/eonasdan-bootstrap-datetimepicker/src/js/locales/bootstrap-datetimepicker.de',
'bootstrap': '../../bower_components/bootstrap/dist/js/bootstrap',
'jquery-cropbox': '../../bower_components/jquery-cropbox/jquery.cropbox',
'jquery-geocomplete': '../../bower_components/jquery-geocomplete/jquery.geocomplete',
'seiyria-bootstrap-slider': '../../bower_components/seiyria-bootstrap-slider/js/bootstrap-slider',
'leaflet': '../../vendor/leaflet/leaflet-custom',
modernizr: '../../bower_components/modernizr/modernizr',
intro: '../../bower_components/intro.js/intro',
lightbox2: '../../bower_components/lightbox2/js/lightbox'
},
shim: {
'underscore.deepExtend': 'underscore',
'underscore.string': 'underscore',
'parsleyjs': 'jquery',
'eonasdan-bootstrap-datetimepicker': 'moment',
'parsleyjs-comparison': 'parsleyjs',
'parsleyjs-de': 'parsleyjs',
'select2-de': 'select2',
'lightbox2': 'jquery',
'jquery.simplePagination': 'jquery',
'bootstrap-select': 'bootstrap',
'bootstrap-slider': 'bootstrap',
'backbone.modelbinder': 'backbone',
underscore: {
deps: ['jquery'],
exports: '_'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
'backbone.analytics': {
deps: [
'underscore',
'backbone'
],
exports: 'Backbone.Analytics'
},
'backbone.deepmodel': {
deps: [
'underscore',
'backbone'
]
},
marionette: {
deps: [
'backbone'
],
exports: 'Backbone.Marionette'
},
leaflet: {
exports: 'L'
},
'jquery-geocomplete': {
deps: [
'jquery',
'general/googlemaps'
]
}
}
});
require(['infrastructure'], function() {
'use strict';
console.log('infrastructure');
require(['app', 'model/session'], function(App, Session) {
console.log('app, model/session');
App.session = Session;
App.session.login(function() {
App.start();
});
});
});
the build.js part included in my grunt configuration
requirejs: {
compile: {
options: {
mainConfigFile: 'app/scripts/main.js',
paths: {
jquery: 'empty:'
},
modules: [{
name: 'main',
exclude: [
'infrastructure'
]
}, {
name: 'infrastructure'
}],
findNestedDependencies: true,
preserveLicenseComments: false,
stubModules: ['text'],
inlineText: true,
optimize: 'none',
dir: '<%= build.dest %>/app/scripts/',
wrapShim: true
}
}
}
On the first step I only wanted to include jquery from a CDN. After the build process I've got two files a main.js and the infrastrucute.js. But if I try to run the application that error message is thrown in the console:
Uncaught Error: Bootstrap's JavaScript requires jQuery
I thought this problem wont occur, because the app requires the manufacture-module before all other parts of the application and the dependent libraries were loaded in the main.js. But it seems that all dependencies within main.js are still being loaded before the manufacture-module.
At the moment I'm a bit confused and don't know how to go on or even where to start.
Does anybody has already optimized apps from that size using r.js with libs from CDN. In addition what do you think about the concatenating/minification process + loading libs from a CDN at all? Does it boost the loading performance really?
thx in advance
Add a dependancy on JQuery for Bootstrap. When JQuery was loaded from your server, it is loaded fast enough to be available when Bootstrap starts. Now that JQuery comes from a CDN, it takes more time to be loaded, and is not available when Bootstrap starts.

Modernizer is undefined when resolved by requirejs

I'm using RequireJS 2.1.6.
Here's the main.js file:
requirejs.config({
paths: {
baseUrl: "/Scripts",
products: "Products/products",
jquery: "jquery-2.0.2.min",
modernizr: "modernizr-2.6.2"
},
shim: {
jquery: {
exports: "$"
},
modernizr: {
exports: "modernizr"
}
}
});
Here is the Products.js file declaration:
define(["modernizr"], function (modernizr) {
// Rest of code.
});
The problem is that modernizr is undefined when I execute the code in Products.js. If I remove the parameter modernizr and instead use the Modernizr variable instead (which is naturally exposed by Modernizer.js globally), then the code works fine. However, this is not my ideal setup.
I've double-checked the spelling, and the config, but I cannot understand why this is the case. I assume I've missed a fundamental point here, so I'm hoping someone can explain where I've gone wrong.
Try this:
requirejs.config({
paths: {
baseUrl: "/Scripts",
products: "Products/products",
jquery: "jquery-2.0.2.min",
modernizr: "modernizr-2.6.2"
},
shim: {
jquery: {
exports: "$"
},
modernizr: {
exports: "Modernizr"
}
}
});
Modernizr exposes Modernizr and not modernizr.

Can't use requirejs

I'm newby in require.js.
I have next trouble.
I linked require.js :
<script data-main="/Scripts/page/main" src="/Scripts/framework/require.js"></script>
code main.js
require.config(
{
shim: {
backbone: {
exports: 'backbone'
}
},paths: {
jquery: "/Scripts/framework/jquery/jquery-1.6.4",
underscore: "/Scripts/framework/underscore/underscore",
backbone: "/Scripts/framework/backbone/backbone"
}
});
require(["jquery"], function (jquery) {
// why jquery is undefined?
})
I tried to use it like in manual, but unfortunately it's doesnt work.
Why in require function jquery variable is undefined?
Thanks for any help.
The problem is that your baseUrl, where requireJs will load the script from, is the one you specify in the data-main attribute. From the docs:
If no baseUrl is explicitly set in the configuration, the default
value will be the location of the HTML page that loads require.js. If
a data-main attribute is used, that path will become the baseUrl.
According to this, your paths need to look like this:
require.config({
shim: {
backbone: {
exports: 'backbone'
}
},
paths: {
jquery: "../Scripts/framework/jquery/jquery-1.6.4",
underscore: "../Scripts/framework/underscore/underscore",
backbone: "../Scripts/framework/backbone/backbone"
}
You could also set the baseUrl to the root of your project like this:
require.config({
baseUrl: "./",
shim: {
backbone: {
exports: 'backbone'
}
},
paths: {
jquery: "Scripts/framework/jquery/jquery-1.6.4",
underscore: "Scripts/framework/underscore/underscore",
backbone: "Scripts/framework/backbone/backbone"
}
I just ran through the same problem.
Im also new in it but I found a good solution explained here Loading Backbone and Underscore using RequireJS
Basically is extend the shim to:
requirejs.config({
baseUrl: 'js/lib',
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'backbone'
}
},
paths: {
app: '../app',
jquery: 'jquery-1.10.2.min',
backbone: 'backbone.min',
underscore: 'underscore.min'
}
});
requirejs(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
console.log('here');
});
Seems underscore _ and backbone depending on both jquery and underscore cause this.
It works for me and makes sense.
Please correct me If it doesnt.

Resources