RequireJS loading leaf modules - javascript

I'm new to RequireJS but seem to be hitting a brick wall.
The trouble starts with my "app" module. I'm not sure how to tell RequireJS to load my leaf modules - packages that depend on "app".
I think I understand why - since nothing in the system depends on them and they aren't registered anywhere, but I need to deal with this case.
How can I let RequireJS know about these modules and to load them appropriately?
Cheers
//index.html
....
<script data-main="app/config" src="/assets/js/libs/require.js"></script>
....
//config.js
require.config({
deps: [ "app" ],
paths: {
libs: "../assets/js/libs",
plugins: "../assets/js/plugins",
jquery: "../assets/js/libs/jquery",
underscore: "../assets/js/libs/underscore",
backbone: "../assets/js/libs/backbone",
marionette: "../assets/js/libs/backbone.marionette"
}
});
//app.js
require(
[ "jquery", "underscore", "backbone", "marionette" ],
function ( $, _, Backbone, Marionette ) {
//....
}
);
//app.view.js
require(
[ "jquery", "underscore", "backbone", "marionette", "app" ],
function ( $, _, Backbone, Marionette, App ) {
//....
}
);
//app.route.js
require(
[ "backbone", "app" ],
function ( Backbone, App ) {
//....
}
);
Hence:
app.js depends on "jquery", "underscore", "backbone", "marionette"
app.view.js depends on "jquery", "underscore", "backbone",
"marionette", "app" app.route.js depends on "backbone", "app"

As stated in the docs ->
http://requirejs.org/docs/api.html#config
dependencies are defined in the deps array. They are the first thing that's loaded when require.js is run, it's really mostly used when you have to define dependencies before you load require.js.
this is what your structure should look like
//config.js
require.config({
paths: {
libs: "../assets/js/libs",
plugins: "../assets/js/plugins",
jquery: "../assets/js/libs/jquery",
underscore: "../assets/js/libs/underscore",
backbone: "../assets/js/libs/backbone",
marionette: "../assets/js/libs/backbone.marionette"
}
});
require(['app']);
//app.js
define(
[ "jquery", "underscore", "backbone", "marionette" ],
function ( $, _, Backbone, Marionette ) {
//....
}
);
//app.view.js
define(
[ "jquery", "underscore", "backbone", "marionette", "app" ],
function ( $, _, Backbone, Marionette, App ) {
//....
}
);
//app.route.js
define(
[ "backbone", "app" ],
function ( Backbone, App ) {
//....
}
);
Bear in mind that all your libraries and modules need to be AMD compliant and if you want to use app as a path like in app.view.js then you need to define it as one. The same with egis, because you can't load modules like so [ "Backbone", "App" ] if they are not defined in require.config as paths.

This is how I startup:
// main.js
define(["jquery", "app", "router"], function ($, App) {
"use strict";
// domReady plugin maybe best used here?
$(function() {
App.start();
});
});
// app.js
define(["backbone", "marionette"], function (Backbone) {
"use strict";
var app = new Backbone.Marionette.Application();
app.on("initialize:after", function(options){
if (Backbone.history){
Backbone.history.start();
}
});
return app;
});
// router.js
define(["backbone", "controller", "marionette"], function(Backbone, controller) {
"use strict";
var Router = Backbone.Marionette.AppRouter.extend({
appRoutes: {
"": "index"
}
});
return new Router({
controller: controller
});
});
// controller.js
define(["view"], function(View) {
return {
"index": {
new View(); // Do what you like hereā€¦
}
}
});
// view.js
define(["backbone"], function(Backbone) {
// view here
});
I assume that the dependency to router.js could be put on app.js but basically the call to Backbone.history.start() needs routers to be loaded.
The router has a dependency on the controller. It's the controller that has all the dependencies to the views etc that is used by it. There could be models and collections etc.
Hope that helps.

Related

Marionettejs Routes

I'm new to Marionette and I just can't get routes to work.
I'm using Marionette's 2.4.1 version, and trying to do it the simplest way possible so it'll just work.
This code works for old version of Marionette, v1.0.2, which was included in one of the yeoman's generator. I know there's a huge gap between those two versoins but for every post, blog, official documentation and even books written for this framework code stays the same.
There are no errors in console, but the 'home' method just won't start.
Am I missing something here?
application.js (Application body):
define(['backbone', 'marionette'],
function (Backbone, Marionette) {
'use strict';
var App = new Marionette.Application();
App.Router = Marionette.AppRouter.extend({
appRoutes: {
"home": "home"
}
});
var myController = {
"home": function() {
console.log("This thing just won't work.");
}
};
/* Add initializers here */
App.addInitializer(function () {
console.log('App initialized');
new App.Router({
controller: myController
});
});
App.on("initialize:after", function () {
if (Backbone.history) {
Backbone.history.start();
}
});
return App;
});
main.js (Starts our app defined in application.js):
require(['marionette', 'application'],
function ( Marionette, App ) {
'use strict';
App.start();
});
config.js (Config for require.js)
require.config({
baseUrl: "/scripts",
/* starting point for application */
deps: ['marionette', 'main'],
shim: {
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
marionette: {
deps: ['backbone'],
exports: 'Marionette'
}
},
paths: {
backbone: '../bower_components/backbone/backbone',
jquery: '../bower_components/jquery/dist/jquery',
underscore: '../bower_components/underscore/underscore',
/* alias all marionette libs */
'marionette': '../bower_components/marionette/lib/core/backbone.marionette',
'backbone.wreqr': '../bower_components/backbone.wreqr/lib/backbone.wreqr',
'backbone.babysitter': '../bower_components/backbone.babysitter/lib/backbone.babysitter'
}
});
It looks like you're missing a reference to the router's controller.
Try updating the Router to include a reference to myController:
App.Router = Marionette.AppRouter.extend({
controller: myController,
appRoutes: {
"home": "home"
}
});
See AppRouter docs for more infomation:
http://marionettejs.com/docs/v2.4.1/marionette.approuter.html
It seems that initialize:after in:
App.on("initialize:after", function () {
if (Backbone.history) {
Backbone.history.start();
}
});
isn't supported in newest versions of Marionette and I was supposed start instead:
App.on("start", function () {
if (Backbone.history) {
Backbone.history.start();
}
});
Most posts about Marionette seems to be rather outdated. Those are still really helpful but be sure to verify it with the official framework's documentation.
I should've done that in the first place..

backbone loaded with requirejs shim but still Backbone undefined error

I've read many answers and followed steps I could ( seems right to me) but still DevTools shows Backbone is not defined. error.
Here's how I use requirejs shim.
<script data-main="js/subject_main.js" src="js/libs/require.js"></script>
subject_main.js
require.config({
paths: {
bootstrap: '../libs/bootstrap.min',
jquery: '../libs/jquery',
underscore: '../libs/underscore',
backbone: '../libs/backbone',
text: '../libs/text',
json2: '../libs/json2',
templates: '../../templates'
},
shim: {
'boostrap':{
deps: ['jquery']
},
'backbone': {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
}
}
});
require(['subjects', 'json2'], function(app) {
app.initialize();
});
subjects.js
define(['jquery', 'underscore', 'backbone', 'subject_router'], function($, _, Backbone, router) {
return {
initialize: function() {
Backbone.history.start();
}
};
});
subject_router
define([
'jquery',
'underscore',
'backbone',
'models/subject_item_model',
'collections/subjects_collection',
'views/subject_view'
],function($, _, Backbone) {
var AppRouter = Backbone.Router.extend({ ... });
return new AppRouter();
});
Chrome DevTools shows following sequence (order ) of scripts -
As you can see, backbone is loaded at very end. I don't know what's going wrong and where.
backbone.js or underscore.js look fine to me here, and indeed they are being loaded!
The 404s in your dev tool are referring to the source mapping files (underscore.min.map). You might want to look at this post: Missing Javascript ".map" file for Underscore.js when loading ASP.NET web page.
PS: In your subject_router code you have a mismatch on the arguments passed in to the module function.

Import and using javascript library in backbone.js project

I'm newbie to backbone.js and require.js. Currently I create one backbone project.
Here is app.js code :
define([
'jquery',
'underscore',
'backbone',
'script',
'router'
], function($, _, Backbone, Script, Router){
var initialize = function(){
Router.initialize();
};
return {
initialize: initialize
};
});
Here is main.js:
require.config({
path: {
jquery: 'libs/jquery/jquery-min',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-min',
script: 'libs/scripts/index'
},
shim:{
backbone: ['jquery', 'underscore'],
script: ['jquery'],
enforceDefine: true
}
});
require([
'app',
], function(App){
App.initialize();
});
And the last one is router.js :
define([
'jquery',
'underscore',
'backbone',
'script'
], function($, _, Backbone){
var AppRouter = Backbone.Router.extend({
routes:{
'*actions': 'defaultAction'
}
});
var initialize = function(){
var app_router = new AppRouter;
app_router('route:defultAction', function(actions){
});
Backbone.history.start();
};
return {
initialize: initialize
};
});
I want to add jquery-json library to my project. If in html project, here is my code :
<script type="text/javascript" src="jquery-min.js"></script>
<script type="text/javascript" src="jquery.json-2.4.min.js">
</script>
<script>
function serializeObjToJSON(_obj) {
var _json = $.toJSON(_obj);
return _json;
}
function deserializeJSONToObj(_json) {
var _obj = $.evalJSON(_json);
return _obj;
}
</script>
I want to import the library above and using it in my backbone project. But I have no idea how to do that.
Any help would be much appreciated, thank you.
in your main JS you should add the JSON reference. (put jquery.json-2.4.min.js into lib/ folder)
require.config({
path: {
jquery: 'libs/jquery/jquery-min',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-min',
script: 'libs/scripts/index',
json: 'libs/jquery.json-2.4.min'
}
Then you can add it as a definition into the app.js or any other module.js file which is using it in reference .
define([
'jquery',
'underscore',
'backbone',
'script',
'router',
'json'
], function($, _, Backbone, Script, Router, Json){
//Code
}
Then within your js files you have your reference to json. You can call it by using
Json.method()
for example.. As soon as you write json, it looks for your definition and then reffers to that lib for the functions you called.
So your index.js or whichever end you want to call it will require something like :
define([
'jquery',
'underscore',
'backbone',
'script',
'router',
'json'
], function($, _, Backbone, Script, Router, Json){
serializeObjToJSON: function(_obj) {
var _json = Json.toJSON(_obj);
return _json;
}
deserializeJSONToObj: function(_jsonObject) {
var _returnObj = Json.evalJSON(_jsonObject);
return _returnObj;
}

jQueryMobile and backbone - how to load "routers/mobileRouter"

I'm trying to setup a project using jQueryMobile, Backbone and RequireJs. Here is the relevant code snippet:
require([ "jquery", "backbone", "routers/mobileRouter" ],
function( $, Backbone, Mobile ) {
/* do something */
}
) ;
It is actually coming from here. Running the code gives a 404 on 'routers/mobileRouter'
GET http://localhost:9000/scripts/routers/mobileRouter.js 404 (Not Found)
For example, if I search for 'mobileRouter.js' in my project I get the following
./app/bower_components/jquery-mobile/demos/examples/backbone-require/js/routers/mobileRouter.js
./app/bower_components/jquery-mobile/dist/demos/examples/backbone-require/js/routers/mobileRouter.js
These are demos/examples, so how should I load this, maybe I need to install an other package ? Any link to some documentation about this would of course help me too!
UPDATE: here is all the js code
// Sets the require.js configuration for your application.
require.config( {
// 3rd party script alias names (Easier to type "jquery" than "libs/jquery-1.8.3.min")
paths: {
// Core Libraries
jquery: '../bower_components/jquery/jquery',
backbone: '../bower_components/backbone/backbone',
underscore: '../bower_components/underscore/underscore',
jquerymobile:'../bower_components/jquery-mobile/dist/jquery.mobile.min'
},
// Sets the configuration for your third party scripts that are not AMD compatible
shim: {
"backbone": {
"deps": [ "underscore", "jquery" ],
"exports": "Backbone" //attaches "Backbone" to the window object
},
"jquery.mobile": ['jquery']
} // end Shim Configuration
} );
// Includes File Dependencies
require([ "jquery", "backbone", "routers/mobileRouter" ], function( $, Backbone, Mobile ) {
$( document ).on( "mobileinit",
// Set up the "mobileinit" handler before requiring jQuery Mobile's module
function() {
// Prevents all anchor click handling including the addition of active button state and alternate link bluring.
$.mobile.linkBindingEnabled = false;
// Disabling this will prevent jQuery Mobile from handling hash changes
$.mobile.hashListeningEnabled = false;
}
);
require( [ "jquerymobile" ], function() {
// Instantiates a new Backbone.js Mobile Router
this.router = new Mobile();
});
} );
Just add another key/value to your paths:
paths: {
// Core Libraries
jquery: '../bower_components/jquery/jquery',
backbone: '../bower_components/backbone/backbone',
underscore: '../bower_components/underscore/underscore',
jquerymobile:'../bower_components/jquery-mobile/dist/jquery.mobile.min',
jquerymobilerouter: '../bower_components/jquery-mobile/demos/examples/backbone-require/js/routers/mobileRouter.js'
},
then you can use it like this:
require(["jquery", "backbone", "jquerymobilerouter"], function($, Backbone, MobileRouter) {
});

amd and coffeescript

I am working on a combination of coffeescript and require.js for AMD.
The problem would be that I must return a value for each module loaded by require.js, and I do that. But.. coffeescript helps me out and appends:(function() { and }).call(this);. which blows my code.
main.js
require.config( {
paths: {
'backbone': 'libs/AMDbackbone-0.5.3',
'underscore': 'libs/underscore-1.2.2',
'text': 'libs/require/text',
'jquery': 'libs/jquery-1.7.1',
},
baseUrl: '/app'
} );
require(
['require', 'backbone', 'jquery', 'underscore' ],
function( require, Backbone, $, _ ) {
// framework loaded
require(
['require', 'app'],
function( require, app) {
return {};
} );
} );
app.js
define( [
'jquery',
'underscore',
'backbone',
'views/gameview',
], function( $, _, Backbone, GameView, ) {
"use strict";
window.app = {};
$(function(){
var app = window.app = _.extend({
views: {
GameView: new GameView
},
//code..
}, window.app);
//code...
return window.app;
} );
And the coffeescript:
/views/gameview.coffee
define ["jquery", "underscore", "backbone"], ($, _, Backbone, RankView) ->
"use strict"
GameView = Backbone.View.extend()
GameView
Which translates to:
/views/gameview.js
(function() {
define(["jquery", "underscore", "backbone"], function($, _, Backbone) {
"use strict";
var GameView;
GameView = Backbone.View.extend({...});
return GameView;
});
}).call(this);
But I would like to translate to:
define(["jquery", "underscore", "backbone"], function($, _, Backbone) {
"use strict";
var GameView;
GameView = Backbone.View.extend({...});
return GameView;
});
Would be nice to use this in console: var GameView = new app.views.GameView; in console.
How do I force coffeescript compiler not to do that? Is there a flag or something for that?
AGAIN: I JUST WANT TO CUT OFF (function() { and }).call(this); - is not that important the amd code behind it, be it global or not..
Thank you
You can use the --bare flag when compiling your coffee files:
-b, --bare Compile the JavaScript without the top-level function safety wrapper.

Categories