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
Related
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.
i'm trying to use almond.js in grunt to combine my files into on .js and uglify it.
My configuration in grunt is like this:
requirejs: {
compile: {
options: {
baseURL: "www/js/lib",
mainConfigFile: 'www/js/main.js',
name: '../../../node_modules/almond/almond',
include: '../main',
out:'../target/app.min.js',
findNestedDependencies: true,
optimize: 'uglify',
}
}
},
my main.js is this:
require.config({
baseUrl: "js/lib",
paths: {
app: '../app',
tpl: '../tpl'
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'backbone-indexeddb': {
deps: ['backbone', 'IndexedDBShim']
},
'IndexedDBShim': {
deps: ['backbone']
}
}
});
If i try to run grunt requirejs i get an error:
Error: Error: ERROR: module path does not exist: project/www/js/js/lib/../../../node_modules/almond/almond.js for module named: ../../../node_modules/almond/almond. Path is relative to: project
at /project/node_modules/grunt-contrib-requirejs/node_modules/requirejs/bin/r.js:25964:35
which i do not understand, where does the second /js/ in the path come from? It does not exist in my file structure, i have my project folder set up like this
project
gruntfile
node_modules
almond
almond.js
www
index.html
js
app
lib
main.js
Oh, i'm configuring the baseurl twice, shouldn't do that. If i remove the baseurl parameter in the gruntfile it works fine.
I am getting following error
uncaught exception: Please include Backbone.ModelBinder.js before Backbone.CollectionBinder.js
after doing
node r.js -o build.js
My build.js file is
({
"mainConfigFile": 'js/main.js',
"name": "main",
"include": [
"lib/require/require-with-comments.js"
],
"exclude": [],
"optimize": "uglify2",
"out": "main-built.js",
"insertRequire": [
"js/main"
]
})
My require config is as follows
require.config({
// The shim config allows us to configure dependencies for
// scripts that do not call define() to register a module
urlArgs: "bust=" + (new Date()).getTime(),
shim: {
'underscore': {
exports: '_'
},
'bootstrap': {
deps: [
'jquery'
]
},
'backbone': {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
}, 'handlebars': {
exports: 'Handlebars'
}, 'handlebarsview': {
deps: [
'backbone',
'handlebars'
],
exports: 'HandlebarsView'
}, 'highcharts': {
deps: [
'jquery'
],
exports: 'highcharts'
}
, 'collectionbinderview': {
deps: [
'backbone',
'jquery',
'underscore',
'modelbinderview'
]
}, 'purl' : {
deps : ['jquery']
}
, 'select2': {
deps: [
'jquery'
],
exports: 'select2'
}
, 'customSelect': {
deps: [
'jquery'
],
exports: 'customSelect'
}
, 'datepicker': {
deps: [
'jquery',
'momentjs'
],
exports: 'datepicker'
}
},
paths: {
jquery: 'lib/jquery/jquery.min',
bootstrap: 'lib/bootstrap/bootstrap',
underscore: 'lib/lodash/lodash.min',
backbone: 'lib/backbone/backbone',
text: 'lib/require/text',
handlebars: 'lib/view/hacked-handlebars-1.0.0',
handlebarsview: 'lib/view/backbone.handlebars',
collectionbinderview: 'lib/view/Backbone.CollectionBinder',
modelbinderview: 'lib/view/Backbone.ModelBinder',
highcharts: 'lib/charting/highcharts',
momentjs: 'lib/view/moment',
select2: 'lib/select2/select2',
customSelect: 'lib/customSelect/customSelect',
datepicker: 'lib/view/datepicker',
purl : 'lib/purl/purl'
}
});
Can anyone please tell me what wrong am I doing?
collectionbinderview: 'lib/view/Backbone.CollectionBinder',
modelbinderview: 'lib/view/Backbone.ModelBinder',
Try to switch them. Place ModelBinder before CollectionBinder.
This problem occurred because CollectionBinder executed as soon as it was loaded, whereas ModelBinder was an AMD and thus not yet defined. In short CollectionBinder was not an AMD library.
I got above solution from following issue:
https://github.com/theironcook/Backbone.ModelBinder/pull/111
and commit is
https://github.com/rweng/Backbone.ModelBinder/commit/9e93e7c9236ccef71c87a3dc4023910f9ac03803
My Gruntfile.js file:
module.exports = function (grunt) {
grunt.initConfig({
pkg : grunt.file.readJSON('package.json'),
requirejs : {
compile: {
options: {
baseUrl: "public_html/js",
mainConfigFile: "public_html/js/config.js",
out: "public_html/app.min.js"
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', ['requirejs']);
};
My config.js file:
'use strict';
require.config({
deps: ['main'],
paths: {
jquery: 'vendor/jquery',
jquery_tokeninput: 'vendor/jquery.tokeninput',
underscore: 'vendor/underscore',
backbone: 'vendor/backbone'
},
shim: {
jquery: [],
jquery_tokeninput: {
deps: ['jquery']
},
backbone: {
deps: ['vendor/underscore', 'vendor/jquery', 'vendor/jquery.tokeninput'],
exports: 'Backbone'
},
underscore: {
exports: '_'
}
}
});
require(['views/app'], function(AppView) {
new AppView;
});
When I run grunt requirejs it errors with:
Running "requirejs:compile" (requirejs) task
[Error: Error: Missing either a "name", "include" or "modules" option at function.build.createConfig (D:\project\node_modules\grunt-contrib-requirejs\node_modules\requirejs\bin\r.js:24829:19)]
First time using gruntjs and requirejs so not sure why I'm getting the error.
Updated the grunt.js file to use name:
module.exports = function (grunt) {
grunt.initConfig({
pkg : grunt.file.readJSON('package.json'),
requirejs : {
compile: {
options: {
name: "views/app",
baseUrl: "public_html/js",
mainConfigFile: "public_html/js/config.js",
out: "public_html/app.min.js"
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', ['requirejs']);
};
and removed the following from the config.js:
require(['views/app'], function(AppView) {
new AppView;
});
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