Web application using backbone, underscore, jquery, bootstrap etc - javascript

I'm working on my first javascript based web application and wanted to leverage a few different frameworks that I've been looking into but I'm having a lot of trouble getting all my different libraries loaded properly. I am trying to use Backbone and Underscore as well as the javascript included with Twitter Bootstrap (which I'm using for my CSS/HTML scaffolding). This is my butchered attempt at loading all of the scripts but I'm still getting firebug errors coming out of of require.js
As per the suggested answers I have edited my setup. In my index.html:
<script data-main="../scripts/main.js" src="../scripts/require.js"></script>
And in main.js:
require.config({
// Require is defined in /scripts, so just the remaining path (and no ext needed)
'paths': {
"bootstrap": "scripts/bootstrap",
"jquery": "scripts/jquery",
"underscore": "scripts/underscore",
"backbone": "scripts/backbone"
},
'shim':
{
backbone: {
'deps': ['jquery', 'underscore'],
'exports': 'Backbone'
},
underscore: {
'exports': '_'
}
}
});
require([
'jquery',
'bootstrap',
'underscore',
'backbone'
],
function(bootstrap, $, _, Backbone){
Person = Backbone.Model.extend({
initialize: function () {
alert("Welcome to this world");
}
});
var person = new Person;
});
But I am still getting script errors from require.js that points to this link
http://requirejs.org/docs/errors.html#scripterror

From a glance it looks like it's the setup of RequireJS, take a look at this: https://github.com/jcreamer898/RequireJS-Backbone-Starter
You don't need to define your scripts in the body, those should be loaded through Require, so something like:
Your main index.html:
<script src="path/to/require.js" data-main="scripts/app">
Then the data-main reference would point to something like /scripts/app.js with the following:
require.config({
// Require is defined in /scripts, so just the remaining path (and no ext needed)
'paths': {
"bootstrap": "libraries/bootstrap"
"jquery": "libraries/jquery",
"underscore": "libraries/underscore-min",
"backbone": "libraries/backbone-min"
},
'shim':
{
backbone: {
'deps': ['jquery', 'underscore'],
'exports': 'Backbone'
},
underscore: {
'exports': '_'
}
}
});
require([
'bootstrap',
'jquery',
'underscore',
'backbone'
],
function(bootstrap, $, _, Backbone){
// Start your application here...
});

With RequireJS the only library you should include in the <script /> tags is require.js. In addition you need to specify a "main" javascript file, which should be loaded by RequireJS:
<script data-main="scripts/main.js" src="scripts/require.js"></script>
The main file should then load other libraries:
requirejs(['jquery','backbone'], function ($,Backbone) {
//...
});
I suggest you read through the RequireJS API documentation and follow the examples.

Nobody has made the point that maybe you are starting with so many components (each with its concepts to learn) to be your first time Javascript project. I would try to explore each of the libraries separately before in really simple projects, have some experience with them and when you have a clear picture of what they do (docs don't always give it) you can start combining them all.
Possibly not the answer you were looking for, but it's my experience who's talking here. Good luck!

Related

What does requirejs.config() do?

I am having trouble understanding about requirejs.config() function.
requirejs.config({
paths: {
'text': '../lib/require/text',
'durandal':'../lib/durandal/js',
'plugins' : '../lib/durandal/js/plugins',
'transitions' : '../lib/durandal/js/transitions',
'knockout': '../lib/knockout/knockout-3.1.0',
'bootstrap': '../lib/bootstrap/js/bootstrap',
'jquery': '../lib/jquery/jquery-1.9.1'
},
shim: {
'bootstrap': {
deps: ['jquery'],
exports: 'jQuery'
}
}
});
What does the function do? Please do not direct me to the documentation because I have read it and still found it confusing. I need a simple explanation on what this function does.
Are these scripts loaded asynchronously?
It creates aliases for script paths ant tells how to interpret bootstrap (non-AMD script) when loaded. Nothing is loaded yet. You have to require:
// we load two dependencies here
// `knockout` and `bootstrap` are expanded to values in config
// .js added to values
// callback function called when all dependencies are loaded
require(['knockout', 'bootstap'], function(Knockout, $) {
// jQuery is passed to this function as a second parameter
// as defined in shim config exports
});
The path is like declarations/definitions. So for example,
jquery: '../bower_components/jquery/dist/jquery',
you can later load this lib as follows.
define([
'jquery'
], function (jquery) {
//initialize or do something with jquery
}
You don't have to specify the absolute path of the library.
In shim, you will define dependencies. So for example,
paths: {
template: '../templates',
text: '../bower_components/requirejs-text/text',
jquery: '../bower_components/jquery/dist/jquery',
backbone: '../bower_components/backbone/backbone',
underscore: '../bower_components/underscore/underscore',
Router: 'routes/router'
},
shim: {
'backbone': ['underscore', 'jquery'],
'App': ['backbone']
}
Here backbone is dependent on underscore and jquery. So those two libs will be loaded before backbone starts loading. Similarly App will be loaded after backbone is loaded.
You might find this repo useful if you are familiar with backbone and express.
https://github.com/sohel-rana/backbone-express-boilerplate

Jsjws JSON Web signatures and tokens

I'm trying to include jsjws in my current project (Backbone, Marionette) which uses RequireJS to include all modules. I have AMD and non AMD scripts included, the non AMD using shims but I'm not sure how jsjws (http://kjur.github.io/jsjws/) will work in this instance. Maybe someone can help?
Current RequireJS config with attempt at including jsjws:
paths: {
backbone: "vendor/backbone", "backbone.syphon":"vendor/backbone.syphon",
jquery: "vendor/jquery",
json2: "vendor/json2",
underscore: "vendor/underscore",
marionette: "vendor/backbone.marionette",
jsjws: "vendor/jws-3.0",
tpl: "vendor/tpl"
},
shim: {
underscore: {
exports: "_"
},
backbone: {
deps: ["jquery", "underscore", "json2"],
exports: "Backbone"
},
"backbone.syphon": ["backbone"],
marionette: {
deps: ["backbone"],
exports: "Marionette"
}
}
many thanks,
Wittner
Looking at the code for jsws and at the documentation, it seems to me that this is what you need to add to your shims:
jsjws: {
exports: "KJUR"
}
Or I believe you could have it export "KJUR.jws" to skip the top level namespace (which seems useless in this context).
I was not able to find a clear list of what dependencies it has. If I look at the various samples in the github repo, the list of files loaded before jsjws seems to vary quite a bit depending on the specific needs of the project. At any rate, whatever your project needs for jsjws to do its job would have to be added to a deps field, and probably these dependencies would get shims of their own.

RequireJS - custom js-library not working

I'm trying to include a custom js-library/script in my RequireJS-config but it doesnt seem to work. So I hope someone can help me out. I'm using RequireJS in combination with Backbone and Handlebars, so just to mention it...
In my Require config I have:
require.config({
paths: {
jquery: 'lib/jquery/jquery',
backbone: 'lib/backbone/backbone',
// Templating.
handlebars: 'lib/handlebars/handlebars',
// Plugins.
jqueryEffects: 'lib/jquery/jquery.effects',
... //some more libraries
},
shim: {
backbone: {
deps: ['jquery', 'lodash','jqueryEffects'],
exports: 'Backbone'
},
lodash: {
exports: '_'
},
handlebars: {
exports: 'Handlebars'
},
jqueryEffects : {
deps: ['jquery']
}
}
});
The jquery.effects.js is a simple script i created my own to handle special click events or run animations etc. When i start to run my backbone app, the console tells me that the script is loaded. So now on one of my Views, I have rendered a HTML file which contains an anchor with a class which serves as an identifier, which after clicking it should trigger something...BUT, nothing happens, so I tried to make an alert in the jquery.effects.js-file:
$(function() {
alert($(".videoname").lenght);
});
This gave me the response undefined. Does anyone maybe have an idea? The same goes when I add more libraries, console says they are loaded, but nothing happens... ?!?!?!??
try this (length not lenght) :
(function() {
alert($(".videoname").length);
})();
That's means that your script is working ;)

Loading mustache using requirejs

I would like to load and use mustache by requirejs.
Maybe this question has already asked:
AMD Module Loading Error with Mustache using RequireJS
Anyway I am trying to figure out how can I fix my code:
main.js
require.config({
paths: {
jquery: 'libs/jquery/jquery',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-optamd3-min',
mustache: "libs/mustache/mustache"
}
});
require([
'views/app'
], function(AppView){
var app_view = new AppView;
});
app.js
define([
'jquery',
'underscore',
'backbone',
"mustache"
], function($, _, Backbone, Mustache) {
console.log($, _, Backbone, Mustache); // <-- *** Mustache is null ***
// ......
}
);
As you can see in the comment on app.js file, Mustache is null...
Should I use another library of Mustache?
Here what I am using Mustache
Looks like Mustache supports AMD modules as of July '12. So it should now work out of the box with a loader such as require.js.
You should just create in your mustache directory a new file mustache-wrap.js which looks like this:
define(['libs/mustache/mustache'], function(Mustache){
// Tell Require.js that this module returns a reference to Mustache
return Mustache;
});
and then your main will be:
mustache: "libs/mustache/mustache-wrap"
Not sure if RequireJS 2.1.0 was out at the time of posting this question (and the answers) but the preferred way of handling this now is using shim config element (more info on project's docs page).
Your main.js would become:
require.config({
paths: {
jquery: 'libs/jquery/jquery',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-optamd3-min',
mustache: "libs/mustache/mustache"
},
shim: {
'mustache': {
exports: 'Mustache'
}
}
});
(...)
That's effectively the same as wrapper suggested #AntoJs, but without the boilerplate code.
...but then, since Mustache supports AMD there's no need to wrap/shim in the first place!
You could probably also do in-line named define in the code that consumes mustache, or somewhere in "main.js" (saves the trouble of creating *-wrap file)
define('mustache', ['libs/mustache/mustache'], function(){
// Tell Require.js that this module returns a reference to Mustache
return Mustache; // from global
});
require(
['jquery','underscore','backbone','mustache']
, function($, _, BB, Mustache){
// use them
}
)

Loading Backbone and Underscore using RequireJS

I'm trying to load Backbone and Underscore (as well as jQuery) with RequireJS. With the latest versions of Backbone and Underscore, it seems kind of tricky. For one, Underscore automatically registers itself as a module, but Backbone assumes Underscore is available globally. I should also note that Backbone doesn't seem to register itself as a module which makes it kind of inconsistent with the other libs. This is the best main.js I could come up with that works:
require(
{
paths: {
'backbone': 'libs/backbone/backbone-require',
'templates': '../templates'
}
},
[
// jQuery registers itself as a module.
'http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js',
// Underscore registers itself as a module.
'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js'
], function() {
// These nested require() calls are just due to how Backbone is built. Underscore basically says if require()
// is available then it will automatically register an "underscore" module, but it won't register underscore
// as a global "_". However, Backbone expects Underscore to be a global variable. To make this work, we require
// the Underscore module after it's been defined from within Underscore and set it as a global variable for
// Backbone's sake. Hopefully Backbone will soon be able to use the Underscore module directly instead of
// assuming it's global.
require(['underscore'], function(_) {
window._ = _;
});
require([
'order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js',
'order!app'
], function(a, app) {
app.initialize();
})
});
I should mention that, while it works, the optimizer chokes on it. I receive the following:
Tracing dependencies for: main
js: "/home/httpd/aahardy/requirejs/r.js", line 7619: exception from uncaught JavaScript throw: Error: Error: Error evaluating module "undefined" at location "/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js":
JavaException: java.io.FileNotFoundException: /home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js (No such file or directory)
fileName:/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js
lineNumber: undefined
http://requirejs.org/docs/errors.html#defineerror
In module tree:
main
Is there a better way of handling this? Thanks!
RequireJS 2.X now organically addresses non-AMD modules such as Backbone & Underscore much better, using the new shim configuration.
The shim configuration is simple to use: (1) one states the dependencies (deps), if any, (which may be from the paths configuration, or may be valid paths themselves). (2) (optionally) specify the global variable name from the file you're shimming, which should be exported to your module functions that require it. (If you don't specify the exports, then you'll need to just use the global, as nothing will get passed into your require/define functions.)
Here is a simple example usage of shim to load Backbone. It also adds an export for underscore, even though it doesn't have any dependencies.
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
}
}
});
//the "main" function to bootstrap your code
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone) { // or, you could use these deps in a separate module using define
});
Note: this simplified code assumes that jquery, backbone and underscore are in files named "jquery.js", "backbone.js" and "underscore.js" in the same directory as this "main" code (which becomes the baseURL for require). If this isn't the case, you'll need to use a paths config.
I personally think with the built-in shim functionality, the advantages of not using a forked version of Backbone & Underscore outweigh the benefits of using the AMD fork recommended in the other popular answer, but either way works.
Update: As of version 1.3.0 Underscore removed AMD (RequireJS) support.
You can use the amdjs/Backbone 0.9.1 and the amdjs/Underscore 1.3.1 fork with AMD support from James Burke (the maintainer of RequireJS).
More info about AMD support for Underscore and Backbone.
// main.js using RequireJS 1.0.7
require.config({
paths: {
'jquery': 'libs/jquery/1.7.1/jquery',
'underscore': 'libs/underscore/1.3.1-amdjs/underscore', // AMD support
'backbone': 'libs/backbone/0.9.1-amdjs/backbone', // AMD support
'templates': '../templates'
}
});
require([
'domReady', // optional, using RequireJS domReady plugin
'app'
], function(domReady, app){
domReady(function () {
app.initialize();
});
});
The modules are properly registered and there is no need for the order plugin:
// app.js
define([
'jquery',
'underscore',
'backbone'
], function($, _, Backbone){
return {
initialize: function(){
// you can use $, _ or Backbone here
}
};
});
Underscore is actually optional, because Backbone now gets its dependencies on its own:
// app.js
define(['jquery', 'backbone'], function($, Backbone){
return {
initialize: function(){
// you can use $ and Backbone here with
// dependencies loaded i.e. Underscore
}
};
});
With some AMD sugar you could also write it like this:
define(function(require) {
var Backbone = require('backbone'),
$ = require('jquery');
return {
initialize: function(){
// you can use $ and Backbone here with
// dependencies loaded i.e. Underscore
}
};
});
Regarding the optimizer error: doublecheck your build configuration. I assume your path configuration is off. If you have a directory setup similar to the RequireJS Docs you can use:
// app.build.js
({
appDir: "../",
baseUrl: "js",
dir: "../../ui-build",
paths: {
'jquery': 'libs/jquery/1.7.1/jquery',
'underscore': 'libs/underscore/1.3.1-amdjs/underscore',
'backbone': 'libs/backbone/0.9.1-amdjs/backbone',
'templates': '../templates'
},
modules: [
{
name: "main"
}
]
})
For reference, as of version 1.1.1 (~Feb '13), Backbone also registers itself as an AMD module. It will work with requirejs without the need to use its shim config. (James Burke's amdjs fork also hasn't been updated since 1.1.0)
Good news, Underscore 1.6.0 now supports requirejs define !!!
versions below this require shims, or requiring underscore.js then blindly hoping that the "_" global variable hasn;t been smashed (which to be fair is a fair bet)
simply load it in by
requirejs.config({
paths: {
"underscore": "PATH/underscore-1.6.0.min",
}
});
I will write down directly, you can read the explaination on requirejs.org, you could use below code as a snippet for your everyday use; (p.s. i use yeoman) (since many things updated, im posting this as of Feb 2014.)
Make sure you included script in your index.html
<!-- build:js({app,.tmp}) scripts/main.js -->
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script>
<!-- endbuild -->
Then, in main.js
require.config({
shim: {
'backbone': {
deps: ['../bower_components/underscore/underscore.js', 'jquery'],
exports: 'Backbone'
}
},
paths: {
jquery: '../bower_components/jquery/jquery',
backbone: '../bower_components/backbone/backbone'
}
});
require(['views/app'], function(AppView){
new AppView();
});
app.js
/**
* App View
*/
define(['backbone', 'router'], function(Backbone, MainRouter) {
var AppView = Backbone.View.extend({
el: 'body',
initialize: function() {
App.Router = new MainRouter();
Backbone.history.start();
}
});
return AppView;
});
I hope I was useful.!
require.config({
waitSeconds: 500,
paths: {
jquery: "libs/jquery/jquery",
jqueryCookie: "libs/jquery/jquery.cookie",
.....
},
shim: {
jqxcore: {
export: "$",
deps: ["jquery"]
},
jqxbuttons: {
export: "$",
deps: ["jquery", "jqxcore"]
}
............
}
});
require([
<i> // Load our app module and pass it to our definition function</i>
"app"
], function(App) {
// The "app" dependency is passed in as "App"
// Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function
App.initialize();
});

Categories

Resources