What is wrong with my requirejs setup? - javascript

My requirejs config file looks correct to me. But when I get into my function to fire up my application, I only have access to jQuery. Could someone look at my config file and tell me what I am doing wrong? Why can't I see Backbone or Underscore and why can I see jQuery? Here is my config file:
require.config({
paths: {
jquery: "libs/jquery/jquery",
underscore: 'libs/underscore/underscore',
backbone: "libs/backbone/backbone"
},
shims: {
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
underscore: {
exports: '_'
}
}
});
require(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
'use strict';
debugger;
});
Thanks for the help.

I think you have shims instead of shim in singular, changing it should fix your issue.
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
}
}

The versions of underscore and backbone you are using are not AMD compliant, so they don't return in the way require.js needs them to. You can just leave them off of your function params and they will be available on the global scope. Otherwise, you are passing undefined into your function as the value of _ and Backbone.
require(['jquery', 'underscore', 'backbone'], function() {
console.log($);
console.log(_);
console.log(Backbone);
});

Related

Handlebars is undefined using Require.js

I'm using Handlebars with Require.js, but for some reasons, Handlebars is undifined.
My config:
require.config({
paths: {
underscore: "lib/underscore-min", //1.8.3
backbone: "lib/backbone-min", //1.2.3
jquery: "lib/jquery-2.1.4.min", //2.1.4
marionette: "lib/backbone.marionette.min", //2.4.3
handlebars: "lib/handlebars.runtime.amd.min", //4.0.5
shim: {
"underscore": {
exports: "_"
},
"backbone": {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
"jquery": {
exports: "jquery"
},
"marionette": {
deps: ["backbone", "jquery"],
exports: "Marionette"
},
"handlebars":{
exports: "Handlebars"
}
}
});
...and than in the same file:
require(["handlebars"], function(Handlebars){
"use strict";
console.log(Handlebars); //undefined
});
In an other file:
define(["handlebars"], function(Handlebars){
"use strict";
console.log(Handlebars); //still undefined
});
I'm also using precompiled templates, which are working perfectly fine, so I have no idea, what could be the problem.
Thanks in advance!
---- SOLUTION ----
As Rajab pointed out, the problem was that I used "handlebars" instead of "handlebars.runtime" so thanks for his help!
You need to use:
require(["handlebars.runtime"], function(Handlebars){`
instead of
require(["handlebars"], function(Handlebars){`
and also shim is used only for modules that don't support AMD. Shim completely useless in your example. All these libraries support AMD. For example look at 16 line in backbone.js:
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
or line 1002 in handlebars.runtime.amd.js
define('handlebars.runtime', ['exports', 'module', './handlebars/base' ... etc
All dependencies already inside it. So you need only paths in config:
require.config({
paths: {
underscore: "lib/underscore-min",
backbone: "lib/backbone-min",
jquery: "lib/jquery-2.1.4.min",
marionette: "lib/backbone.marionette.min",
handlebars: "lib/handlebars.runtime.amd.min",
}
}
require(['handlebars.runtime'], function(HandlebarsOrWhateverNameYouWantItStillWillbeHandlebars){
"use strict";
console.log(HandlebarsOrWhateverNameYouWantItStillWillbeHandlebars);
});
that's all.

Backbone.js and Require.js

I want to create Backbone.js app with Require.js.
But I have an error in console: Uncaught Error: Module name "underscore" has not been loaded yet for context: _. Use require([])
require.config({
baseUrl: 'js/',
paths : {
'jquery' : 'jquery',
'underscore' : 'underscore',
'backbone' : 'backbone',
shim: {
'underscore': {
exports: '_'
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
}
});
define('app', ['jquery','backbone', 'underscore'], function ($, Backbone, _){
var Model = Backbone.model.extend({});
var model = new Model;
});
require(['app','jquery', 'backbone', 'underscore']);
How I can resolve this problem?
You still need to list underscore as a part of paths so you can refer to it in the shims. Also, not sure what your directory structure looks like, but I'm writing this with the assumption that library code is in the /js/libs directory). Finally, note you won't need to require any of the dependencies of app -- the joy of RequireJS is that it'll figure out what to load.
So...
require.config({
baseUrl: 'js/',
paths : {
'jquery' : 'lib/jquery',
'underscore' : 'lib/underscore',
'backbone' : 'lib/backbone',
},
shim: {
'underscore': {
exports: '_'
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
define('app', ['jquery','backbone', 'underscore'], function ($, Backbone, _){
var Model = Backbone.Model.extend({});
var model = new Model({
foo: 'bar'
});
var app = {
model: model
};
// ...
return app;
});
require(['app'], function(App) {
App.model.get('foo'); // <<=== returns 'bar'
});
The shim is mentioned inside the paths object. I am not sure if that is the problem, but wanted to mention that here.
You need Underscore.js as listed in your require statement.

Defining a global App Namespace with Require.js and Backbone

I'm new to Require.js, and I'm trying to do something which I thought would be simple but is starting to be a pain.
I'm trying to define a global namespace for my Backbone application, and load it as a module. Here is my namespace (main.js):
define(
['jquery',
'underscore',
'backbone',
'GlobalRouter'
],
function($, _, Backbone) {
var App= {
Models: {},
Views: {},
Collections: {},
Routers: {},
init: function() {
new App.Routers.GlobalRouter();
Backbone.history.start();
}
}
return App;
});
and here is my config.js file:
require.config({
// your configuration key/values here
baseUrl: "js", // generally the same directory as the script used in a data-main attribute for the top level script
paths: {
'jquery' : '//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min',
'underscore': 'vendor/underscore-min',
'backbone': 'vendor/backbone-min',
'marionette': 'vendor/backbone.marionette',
'main' : 'main'
}, // set up custom paths to libraries, or paths to RequireJS plugins
shim: {
'underscore': {
exports: '_'
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'main' : {
deps: ['underscore', 'jquery', 'backbone', 'GlobalRouter'],
exports: 'TEWC'
}
} // used for setting up all Shims (see below for more detail)
});
define([
'jquery',
'underscore',
'backbone',
'main'
],
function($, _, Backbone, App, GlobalRouter) {
console.log(App)
alert('hit ')
$(function() {
App.init();
});
}
);
and for good measure, here is my router:
define([
'jquery',
'underscore',
'backbone',
'main'
],
function($, _, Backbone, TEWC) {
TEWC.Routers.GlobalRouter = Backbone.Router.extend({
routes: {
"" : "index",
"documents/:id" : "edit",
"login" : "login"
},
edit: function(id) {
alert('edit')
},
index: function() {
alert('index')
},
login: function() {
alert('login')
}
});
});
In the past, I was getting a 'app is undefined error'. Now, I get a load timeout error after a few minutes that says this:
Uncaught Error: Load timeout for modules: main
However, the alert doesn't fire, and main.js doesn't seem to get loaded, but I believe router does, and it doesn't bark that TEWC is undefined -- so it may be loading even though it's not in my Network tab?
This is probably a rookie question -- does anyone have any insight on this?
The following code does not define GlobalRouter yet it get's passed to the define callback
define([
'jquery',
'underscore',
'backbone',
'main'
],
function($, _, Backbone, App, GlobalRouter) {
console.log(App)
alert('hit ')
$(function() {
App.init();
});
}
add GlobalRouter to define
Secondly, when it fails to load main ..can you check from console what URL it is trying to access? It most probably is a mis-configuration.
If I'm not mistaken your problem is that in config.js, after the require.config(), your define() should be a require() instead.
Explaining further. You currently have:
define([
'jquery',
'underscore',
'backbone',
'main'
...
This define should be a require because this is code you want executed; it is not a module definition.
This and of course the missing GlobalRouter dependency as noted earlier.

How to mixin Underscore plugins in RequireJS?

What is the right way to execute code on Underscore when it gets loaded? I am trying to execute the below code to extend the _ exported namespace automatically when modules require it:
_.mixin(_.str.exports());
The docs are a bit vague but I think I put it in the shim init section? I tried the below but I can't even get a breakpoint to hit in the init:
require.config({
paths: {
jquery: 'libs/jquery/jquery.min',
underscore: 'libs/underscore/lodash.min',
underscorestring: 'libs/underscore/underscore.string.min'
},
shim: {
underscore: {
exports: '_'
}
underscorestring: {
deps: ['underscore'],
init: function (_) {
//Mixin plugin to namespace
_.mixin(_.str.exports());
return _;
}
}
}
});
When I try to do this and use underscorestring, I get this error:
Uncaught TypeError: Object function s(e){return new o(e)} has no
method 'startsWith'
Docs:
http://requirejs.org/docs/api.html#config-shim
http://requirejs.org/docs/api.html#config-callback
I don't know if it's the correct way, but I got it working by inverting things so that underscore depends on underscore.string. Also, this way you don't have to require underscore.string.
require.config({
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
deps: ['underscore.string'],
exports: '_',
init: function(UnderscoreString) {
_.mixin(UnderscoreString);
}
}
},
paths: {
'backbone' : 'lib/backbone',
'jquery' : 'lib/jquery/jquery',
'text' : 'lib/require/text',
'underscore' : 'lib/underscore',
'underscore.string' : 'lib/underscore.string'
}
});
.
Update: 3/14/2014
Underscore.js v1.6.0 brought back AMD compatibility and init() has been removed from RequireJS, so some refactoring is in order. To continue getting Underscore preloaded with Underscore.string I made a mixer module to pull them together.
New Require.js config
requirejs.config({
paths: {
'backbone' : '../lib/backbone/backbone',
'backbone.base' : '../lib/backbone/backbone.base',
'backbone.extensions' : '../lib/backbone/backbone.extensions',
'jquery' : '../lib/jquery/jquery',
'text' : '../lib/require/text',
'underscore' : '../lib/underscore/underscore',
'underscore.mixed' : '../lib/underscore/underscore.mixed',
'underscore.string' : '../lib/underscore/underscore.string'
},
shim: {
'backbone.base': {
deps: ['underscore.mixed', 'jquery'],
exports: 'Backbone'
},
}
});
underscore.mixed
define([
'underscore',
'underscore.string'
], function(_, _s) {
_.mixin(_s.exports());
return _;
});
The final step is to replace all instances of 'underscore' with 'underscore.mixed' in module definitions. I attempted moving Underscore into a file named underscore.base.js and making the regular underscore the mixer (like the Backbone setup) to avoid this step. Underscore, being a named module, disagreed with the plan.
Do you require underscorestring somewhere? Because if it isn't required, it won't be loaded.
I managed to get it working with almost exactly the same code you posted:
require.config({
paths: {
underscore: [
'//raw.github.com/documentcloud/underscore/master/underscore-min'
, 'lib/underscore'
]
, underscorestring: 'https://raw.github.com/epeli/underscore.string/master/dist/underscore.string.min'
}
, shim: {
underscore: { exports: '_' },
underscorestring: {
deps: ['underscore'],
init: function(_) {
_.mixin(_.str.exports());
return _; // guess, this is not needed.
}
}
}
, exclude: ['underscore']
});
require(['underscore', 'underscorestring'], function(_) {
console.log( _.chars("i'm a happy string.") );
});
Battling with this for hours before i understand what i was doing wrong
This is what i did wrong
You should not rename the file underscore.string in main.js
even though in my library i did rename the file in paths i name it back to 'underscore.string'
This is how your main.js should look like
require.config({
paths: {
underscore: 'lib/underscore',
'underscore.string' : 'lib/_string' ,
},
shim: {
underscore: {
exports: '_',
deps: [ 'jquery', 'jqueryui' ]
},
'underscore.string': {
deps: [ 'underscore' ]
},
}
....
You could then either add it as dependency with in your shim like i did for my mixin file
shim: {
mixin : {
deps: [ 'jquery', 'underscore', 'underscore.string' , 'bootstrap' ]
},
Or just define it in your different pages like
/*global define */
define([
'underscore.string'
], function ( ) {
it just work now you can access it through _.str or _.string
This is why you should do it this way and not try to name it something else
on line 663 of underscore.string.js
// Register as a named module with AMD.
if (typeof define === 'function' && define.amd)
define('underscore.string', [], function(){ return _s; });
Which means that it will only register it with AMD require JS if you are defining 'underscore.string'
For Mix in you could just with define
/*global define */
define([
'underscore',
'underscore.string'
], function ( ) {
_.mixin(_.str.exports());

handlebars in requirejs load not successfully

paths: {
jquery: 'libs/jquery/jquery-min',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-optamd3-min',
handlebars: 'libs/handlebars/handlebars',
text: 'libs/require/text'
}
define([
'jquery',
'underscore',
'backbone',
'collections/todos',
'views/todos',
'text!templates/stats.html',
'common',
'handlebars'
], function ($, _, Backbone, Todos, TodoView, statsTemplate, Common, handlebars) {
//handlebars is null
console.log("handlebars is",handlebars);
})
Except handlebars,others can load successfully.Why and how to make handlbars load successfully.thanks
Firstly, I can see that you're new but please try to add more detail to your question to help others help you.
From glancing at the source I don't think Handlebars is compatible with AMD, therefore you will need to shim it yourself. Something like this:
requirejs.config({
shim: {
'handlebars': {
exports: 'Handlebars'
}
}
});

Categories

Resources