I'm setting up a app with Require JS and backbone. But in my setup backbone is not loading correctly even if I included all the things
This is my main file.
require.config({
paths: {
/*app: 'app',*/
/*Libs and other resources*/
jquery: 'libs/jquery',
underscore: 'libs/underscore',
backbone: 'libs/backbone'
},
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
}
}
});
require(['backbone'], function (Backbone) {
console.log(Backbone);
});
This is the status of the scripts.
UPDATE:
Removed the shim according to comments. But still its not working.
This happen due to a corrupted backbone.js lib files. I copied this file via a phpstorm from some other place in the project.
I have tried multiple suggestions and non of them are worked. At last I just created a single html file and tried to backbone worked there. Then I realized there may be a problem with backbone.js and just re-downloaded it and replaced. Now everything got to work.
Related
Did anyone successfully loaded moment.js in a r.js build (with almond) ?
I am using backgrid and backgridMomentCell: everything's works perfectly before I build my main.min.js file. After build time moment is not defined and thus can't be found by backgridMomentCell extension.
I've tried several option (even shim) without success.
If somedoby has a require.config that work can he/she shares it ?
EDIT (sorry for not answering any sooner, launch time kept me away from SO):
In the build file BackGridMomentCell keep throwing "moment is not defined" errors.
My code as requested in the comment
requirejs.config({
paths: {
backbone: 'vendor/backbone-1.1.0',
backbonePageable: 'vendor/backbone-pageable-1.4.1',
backgrid: 'vendor/backgrid/js/backgrid-0.2.6',
backgridPaginator: 'vendor/backgrid/js/extensions/paginator/backgrid-paginator',
backgridMomentCell: 'vendor/backgrid/js/extensions/moment-cell/backgrid-moment-cell',
bootstrap: 'vendor/bootstrap/js/bootstrap-3.0.1',
bootstrapDatepicker: 'vendor/bootstrap-datepicker/bootstrap-datepicker-fda46bb',
codemirror: 'vendor/codemirror/js/codemirror-3.20',
codemirrorMarkdown: 'vendor/codemirror/mode/markdown/markdown',
jsDiff: 'vendor/diff-1.0.7',
fullCalendar: 'vendor/fullcalendar/fullcalendar-1.6.4',
fullCalendarJqueryUiCustom: 'vendor/fullcalendar/jquery-ui-1.10.3.custom.min',
jquery: 'vendor/jquery-1.10.2',
marked: 'vendor/marked-0.2.10',
select2: 'vendor/select2/select2-3.4.5',
speakingurl: 'vendor/speakingurl-0.4.0',
underscore: 'vendor/underscore-1.5.2',
moment: 'vendor/moment.with.langs'
},
shim: {
backbone: {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
backgrid: {
deps: ['jquery', 'backbone', 'underscore'],
exports: 'Backgrid'
},
backgridPaginator: {
deps: ['backgrid']
},
backgridMomentCell: {
deps: ['backgrid','moment']
},
bootstrap: {
deps: ['jquery']
},
bootstrapDatepicker: {
deps: ['jquery']
},
codemirror: {
exports: 'CodeMirror'
},
codemirrorMarkdown: {
deps: ['codemirror'],
exports: 'codemirrorMarkdown'
},
fullCalendar: {
deps: ['jquery', 'fullCalendarJqueryUiCustom']
},
fullCalendarJqueryUiCustom: {
deps: ['jquery']
},
select2: {
deps: ['jquery']
},
underscore: {
exports: '_'
}
}
});
The head of my module
define([
'jquery',
'fullCalendar',
'underscore',
'backgrid',
'backgridPaginator',
'moment',
'backgridMomentCell',
'backbone',
'collections/ItemPaginatedCollection',
'utils/BackgridCustomUriCell'
], function ($, _fullCalendar, _, Backgrid, _backgridPaginator, moment, MomentCell,Backbone, ItemPaginatedCollection, BackgridCustomUriCell) {
"use strict";
....
EDIT 3 :
Loading moment.js before my compiled main.js works but is not optimal IMHO.
The easiest two methods I have found:
1) Wrap backgrid-moment-cell.js in the CommonJS wrapper code specified in the RequireJS API. You can do this dynamically during the build process using the conversion tool mentioned in the API.
2) Require moment-cell inline and set findNestedDependencies to false in your build.js.
The issue is that the moment-cell code passes in this to itself when it is initialized, and looks for either "exports.moment" or "this.moment."
On a related note, including moment in the shim for moment-cell is unnecessary, and technically you should include underscore. From the API:
Only use other "shim" modules as dependencies for shimmed scripts, or
AMD libraries that have no dependencies and call define() after they
also create a global (like jQuery or lodash). Otherwise, if you use an
AMD module as a dependency for a shim config module, after a build,
that AMD module may not be evaluated until after the shimmed code in
the build executes, and an error will occur. The ultimate fix is to
upgrade all the shimmed code to have optional AMD define() calls.
Moment is actually an AMD module.
Most likely your problem is that you didn't specify findNestedDependencies true in your build file.
Take a look at this commit (from my book on RquireJS and Backbone.Marionette): https://github.com/davidsulc/structuring-backbone-with-requirejs-and-marionette/commit/85d3d3dd40d0cebd858224c3903a12d6998d668d
I think it's to do with moment's global object being deprecated.
2.4.0 - Deprecate globally exported moment, will be removed in next major
https://github.com/moment/moment
Moment needs to be defined in the specific module now.
I'm following Uzi Kilon's BackboneJS / RequireJS / backbone.LocalStorage example at http://kilon.org/blog/2012/08/build-backbone-apps-using-requirejs/.
When I git clone https://github.com/uzikilon/Todos it works just fine - but it uses older versions of backbone.localstorage. If I replace lib/backbone.localStorage with the newer version http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.0/backbone.localStorage-min, though, then I get "Uncaught TypeError: undefined is not a function" here: https://github.com/uzikilon/Todos/blob/master/js/models/Todo.js#L3 - why? I think this has something to do with the tricky details at http://requirejs.org/docs/api.html#config-shim or perhaps this: http://blog.mostlystatic.com/2013/01/backbone-localstorage-uncaught.html.
require.config({
baseUrl: "./js/",
paths: {
jquery: 'lib/jquery-1.8.2',
underscore: 'lib/underscore-1.4.2',
backbone: 'lib/backbone-0.9.2',
// 'backbone.localStorage': 'lib/backbone.localStorage'
'backbone.localStorage': 'http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.0/backbone.localStorage-min'
},
shim: {
underscore: {
exports: "_"
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'backbone.localStorage': {
deps: ['backbone'],
exports: 'Backbone'
}
}
});
The problem lies with the fact that the latest Backbone localStorage is AMD compatible, where as the version in that example is not, hence the shim config.
The fix
Remove the shim config for backbone.localStorage, you won't be needing it:
'backbone.localStorage': {
deps: ['backbone'],
exports: 'Backbone'
}
Then, in Todo.js change the define call from:
define(['underscore', 'backbone.localStorage'], function(_, Backbone) {
to:
define(['underscore', 'backbone', 'backbone.localStorage'], function(_, Backbone) {
Why?
The shim exports config was being used to say 'When I ask for backbone.localStorage, return me Backbone'.
This allowed 'backbone.localStorage' to be used simply as Backbone inside the Todo module.
But now backbone.localStorage supports AMD and explicitly returns a value from the define call. So the value of Backbone in Todo.js is no longer the Backbone library, but is actually a constructor for Backbone.LocalStorage
As far as I understand, the shim config is ignored for AMD modules, or at least should not be used:
Only use other "shim" modules as dependencies for shimmed scripts, or
AMD libraries that have no dependencies and call define() after they
also create a global (like jQuery or lodash). Otherwise, if you use an
AMD module as a dependency for a shim config module, after a build,
that AMD module may not be evaluated until after the shimmed code in
the build executes, and an error will occur. The ultimate fix is to
upgrade all the shimmed code to have optional AMD define() calls.
To fix things up the additional dependency needs to be added in Todo.js so that so that the callback parameters match up.
Hopefully that makes sense.
My code uses Backbone with Requirejs and jQuery File Upload and works perfectly in IE 9 when I access the development code directly (without building). As soon as I build it something goes wrong and the request is sent empty to the server.
The only difference I see in the request (using Network capturing in IE9) is that the one that works when I click in the upload button, the Initiator is click, and for the one that fails, the initiator is JS Library XMLHttpRequest.
So there must be something making the event change when the code gets compressed, but I have no idea how to get closer to the root of the problem.
Any ideas?
Are you requiring the iFrame Transport plugin?
I am using jQuery File Upload with Requirejs, and have not seen this issue. Without seeing some code, it is hard to say what is tripping up your application. I suggest updating your question with some relevant code. In the meantime, here is what is working for me.
main.js
require.config({
appDir: '../',
baseUrl: 'js/',
paths: {
underscore: '../vendor/lodash.underscore',
backbone: '../vendor/backbone',
'jquery.fileupload': '../vendor/jquery-file-upload/js/jquery.fileupload',
'jquery.iframe-transport': '../vendor/jquery-file-upload/js/jquery.iframe-transport',
'jquery.ui.widget': '../vendor/jquery-file-upload/js/jquery.ui.widget'
},
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
And in the page that houses the upload control:
UploadPage.js
define([
'views/Base',
'jquery.iframe-transport',
'jquery.fileupload'
], function(BaseView) {
return BaseView.extend({
// Do cool stuff
});
});
Backbone doesn't get called in the indexview module.
using requirejs 2.1.5/2.1.4 and backbonejs 0.9.10
main.js after running r.js
...
// this is causing the backbone to return
// null/undefined in the next define call below
define("backbone", function(){});
define('views/index/IndexView', [
'underscore',
'backbone',
'text!templates/index/indexTemplate.html'
], function(_, Backbone, indexTemplate){
console.log(Backbone); // returns undefined
var IndexView = Backbone.View.extend({
...
BUT if I take out the first define call that registers backbone as a module, everything
works fine. but backbone-min.js gets loaded separately. but for now it's the only way
to make the script run. I am definitely missing something here.
main.js
require.config({
paths: {
underscore : 'libs/underscore/underscore-min',
backbone : 'libs/backbone/backbone-min'
templates : '../templates'
},
shim: {
'backbone': {
deps: ['jquery','underscore'],
exports: 'Backbone'
}
}
});
require(['app'], function(App){
App.initialize();
});
build.js
({
appDir: "../",
baseUrl: "js",
dir: "../../build",
optimize: "none",
paths: {
"jquery": "libs/requirejs/require-jquery",
"underscore" : 'libs/underscore/underscore-min',
"backbone": 'libs/backbone/backbone-min',
"templates": '../templates',
},
modules: [
{
name: "main",
exclude: ["jquery"]
}
]
})
I'm still getting my feet wet with backbone and requirejs.
any feedback is much appreciated.
First of all, you don't need that define('backbone',...). What is that part for anyways? You don't need to define Backbone as a module. Requirejs is doing the job of making Backbone available for you to use throughout your framework. As you can see in your code, by calling Backbone.View.extend(), Backbone already exists. If you want to inspect it, don't use console.log, use console.dir instead. In the chrome inspector it formats the output nicely.
Secondly, add underscore to the backbone deps array in your shim.
I've just had this issue, you need to add the 'shim' from your main.js to your build.js file, and will work like a charm ;)
I have a Backbone app that gets errors of Backbone is not defined non-deterministically from different spots in my code that use Backbone. Sometimes it loads first and the site loads, other times it doesn't. I'm using the following as my main.js:
require.config({
paths: {
jqueryui: 'libs/jquery/jquery-ui',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-min',
text: 'libs/require/text',
order: 'libs/require/order',
searchcollector: 'libs/jquery/searchcollector.plugin',
guiders: 'libs/jquery/guiders'
},
shim: {
'underscore': {
exports: '_'
},
'backbone': {
deps: ['underscore'],
exports: 'Backbone'
}
}
});
require([
'views/app',
'helpers'
], function(app) {
var app = window.app = new app();
});
I'm using
<script data-main="/assets/js/main" src="/assets/js/libs/require/require-jquery.js"></script>
in my HTML so jQuery is loaded with the require. I took this advice from this (http://stackoverflow.com/questions/8131265/loading-backbone-and-underscore-using-requirejs) SO thread, but nothing seems to be working. Shouldn't the Shim be loading the Backbone first and then making it globally available? Any help appreciated.
Not sure if this is the correct answer but I've noticed that you don't list jquery as a Backbone dependency. While Backbone lists Underscore as the only hard dependency, Backbone.View will need jquery or zepto to work.
But why then, does it seem to work some of the time?
It might be that since jQuery is an AMD module, when you load, it sometimes loads first, and other times it doesn't. When it loads before Backbone, it is available and Backbone is happy. Otherwise, perhaps, the bad results you are getting.
Try something like this:
In your path add this:
jquery: 'libs/require/require-jquery'
And in your shim, add this:
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
Let me know what you get as a result. I've never used the shim feature of requirejs2.0 so I'm curious whether I'm understanding the deeper stuff correctly.
In my opinion it's a little bit hacky to load require and jquery in the same file.
And set jquery as a deps for Backbone is false because Underscore need jquery, and it's loaded before Backbone so the correct way is like this
require.config({
paths: {
'jquery': 'path to jquery'
,'underscore': 'path to underscore'
,'backbone': 'path to backbone'
**other paths...**
}
,shim: {
jquery: {
exports: '$'
}
,'underscore': {
deps: [ 'jquery' ]
,exports: '_'
}
,'backbone': {
deps: [ 'underscore' ]
,exports: 'Backbone'
}
}
});
Finally your tag script will be
<script data-main="/assets/js/main" src="/assets/js/libs/require.js">
</script>
Then you just have to call lib you need like this
define( [ 'jquery', 'underscore', 'backbone' ],
function( $, _, Backbone )
{
// stuff
} );
And for a model you maybe don't need jquery and underscore so just calling Backbone will work
define( [ 'backbone' ],
function( Backbone )
{
// Backbone.extend ?
} );