I've started a new backbone, marionette and require project using version 2.2 (i previously worked with 1.8) It seems a lot has changed. I'm getting an error when the browser loads marionette:
Uncaught TypeError: Cannot read property 'ChildViewContainer' of undefined
This is my main.js file:
require.config({
baseURL: 'scripts',
paths: {
"jquery": "lib/jquery",
"underscore": "lib/underscore",
"backbone": "lib/backbone",
"marionette": 'lib/backbone.marionette',
"templates": "../templates",
"text": "lib/text"
},
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
marionette: {
deps: ['jquery', 'underscore', 'backbone'],
exports: 'Marionette'
},
waitSeconds: 15
}
});
require([ "app", "marionette"], function(App, marionette) {
App.start();
});
And this is my app.js file:
define(["marionette", "router"], function (Marionette, AppRouter) {
var MyApp = Marionette.Application.extend({
initialize: function(options) {
console.log("options.container");
}
});
var MyApp = new MyApp({container: '#page'});
MyApp.addInitializer(function (options) {
MyApp.Router = new AppRouter();
Backbone.history.start();
});
// export the app from this module
return MyApp;
});
Just look at your backbone.js file. It's empty. Download backbone.js from http://backbonejs.org/ and replace it.
I just ran into this same issue myself. The issue was multiple instances of Marionette being included on the page. (i had errantly placed a script tag for marionette on the page from cdnjs, as well as trying to include the static file locally via require). removing the reference to the external JS file helped me...
Related
I'm loading my dependencies with require.js and I'm getting this error:
backboneforce.js:5 Uncaught SyntaxError: Unexpected token <
My Config file:
require.config({
// Require is defined in /scripts, so just the remaining path (and no ext needed)
'baseUrl': 'js/',
'paths': {
"jquery": "libs/jquery",
"underscore": "libs/underscore",
"backbone": "libs/backbone",
"bootstrap": "libs/bootstrap",
"text": "libs/text",
"notify": "libs/notify",
"backboneForce":"libs/backboneforce",
"forceTK":"libs/forcetk/forcetk",
"forceTKUI":"libs/forcetk/forcetkui"
},
'shim': {
bootstrap: {
deps: ['jquery'],
exports: 'Bootstrap'
},
backbone: {
'deps': ['jquery', 'underscore'],
'exports': 'Backbone'
},
underscore: {
'exports': '_'
},
forceTK:{
deps:['jquery'],
exports:'forcetk'
}
}
});
require([
// Load our app module and pass it to our definition function
'app'
], function (App) {
// The "app" dependency is passed in as "App"
App.initialize();
});
and here is my app.js:
define([
'jquery',
'underscore',
'backbone',
'bootstrap',
'backboneForce',
'forceTK',
'forceTKUI',
'notify',
'router/navigationRouter'
], function ($, _, Backbone, bootstrap, bbforce, forcetk, forcetkui, notify, Router) {
var initialize = function () {
Router.initialize();
console.log(bbforce);
}
return {
initialize: initialize
};
});
In my browser network tab, all dependencies are loaded, but I'm getting this error for forceTK, forceTKUI and backboneForce.
It looks like the path to the backboneforce file is wrong and the server is returning a 404 HTML page.
The following line:
"backboneForce":"libs/backboneforce",
should probably be
"backboneForce":"libs/backboneforce/backboneforce", // or backbone.force
How does require paths work?
Paths inside the paths option are just aliases. If you want to point to a module, you must include the file name without the extension.
If you have the following directory structure:
lib
├───backboneforce
│ └───backbone.force.js
The path should be lib/backboneforce/backbone.force.
Where is the < coming from?
When you make a request with a path to a non-existent file, the server will often return some sort of default 404 error message or it will redirect to a default page (like the home page).
Here's what Stack Overflow returns:
The < comes from <!DOCTYPE html> on the first line of the response, which the browser tries to interpret as JavaScript.
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.
Problem
When executing the compiled handlebars templates the global Handlebars object isn't exported. NOTE: the global Backbone object is working.
See, when the code App.templates.todos attempts to execute in the todos.js file it fails because App.templates.todos isn't defined. Well ultimately that's because the third line in the templates.js file can't execute because the global Handlebars object isn't defined.
Why wouldn't that object get defined? What did I do wrong with require.js here?
UPDATE: I've verified that the handlebars.runtime.js file is in fact executing before the templates.js file and so require.js is running them in the right order when loading the todos.js file.
Bower Components
{
"name": "todomvc-backbone-requirejs",
"version": "0.0.0",
"dependencies": {
"backbone": "~1.1.0",
"underscore": "~1.5.0",
"jquery": "~2.0.0",
"todomvc-common": "~0.3.0",
"backbone.localStorage": "~1.1.0",
"requirejs": "~2.1.5",
"requirejs-text": "~2.0.5",
"handlebars": "~2.0.0"
},
"resolutions": {
"backbone": "~1.1.0"
}
}
main.js
/*global require*/
'use strict';
// Require.js allows us to configure shortcut alias
require.config({
// The shim config allows us to configure dependencies for
// scripts that do not call define() to register a module
shim: {
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
backboneLocalstorage: {
deps: ['backbone'],
exports: 'Store'
},
handlebars: {
exports: 'Handlebars'
},
templates: {
deps: ['handlebars'],
exports: 'App'
},
underscore: {
exports: '_'
}
},
paths: {
jquery: '../bower_components/jquery/jquery',
underscore: '../bower_components/underscore/underscore',
backbone: '../bower_components/backbone/backbone',
backboneLocalstorage: '../bower_components/backbone.localStorage/backbone.localStorage',
handlebars: '../bower_components/handlebars/handlebars.runtime',
templates: '../../../templates',
text: '../bower_components/requirejs-text/text'
}
});
require([
'backbone',
'views/app',
'routers/router'
], function (Backbone, AppView, Workspace) {
/*jshint nonew:false*/
// Initialize routing and start Backbone.history()
new Workspace();
Backbone.history.start();
// Initialize the application view
new AppView();
});
todos.js
/*global define*/
define([
'jquery',
'backbone',
'handlebars',
'templates',
'common'
], function ($, Backbone, Handlebars, Templates, Common) {
'use strict';
var TodoView = Backbone.View.extend({
tagName: 'li',
template: App.templates.todos,
...
});
return TodoView;
});
templates.js
this["App"] = this["App"] || {};
this["App"]["templates"] = this["App"]["templates"] || {};
this["App"]["templates"]["stats"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
From official documentation of RequireJS:
The shim config only sets up code relationships. To load modules that
are part of or use shim config, a normal require/define call is
needed. Setting shim by itself does not trigger code to load.
So first you need to somehow call the Handlebars and after try to use it in templates.js.
I load AngularJs and jQuery using RequireJs in nodeJs framework.
That is main.js
require.config({
paths: {
angular: 'vendor/angular.min',
bootstrap: 'vendor/twitter/bootstrap',
jquery: 'vendor/jquery-1.9.0.min',
domReady: 'vendor/require/domReady',
underscore: 'vendor/underscore.min'
},
shim: {
angular: {
deps: [ 'jquery' ],
exports: 'angular'
}
}
});
require([
'app',
'angular-boot'
], function() {
});
in app.js
define(['angular'], function (angular) {
return angular.module('MyApp', []);
})
and in angular-boot.js
define([ 'angular', 'domReady' ], function (angular, domReady) {
domReady(function() {
angular.bootstrap(document, ['MyApp']);
});
});
In my html file I have only this line, in order to declare and use requirejs.
Not ng-ap or anything else.
<script data-main="js/main" src="js/require.js"></script>
The problem is that sometimes runs, sometimes not.
The error when it doesn't run is
Uncaught Error: No module: MyApp
If there is any thought about it, I would really appreciate it.
Thank you very much.
In your shim, you need to setup the app as a dependency to angular-boot. Your angular-boot file depends on app (where MyApp is defined), and because the load order for these two files is not specified, sometimes angular-boot loads before the app and thus produces that error.
To remedy, just update your shim as such:
shim: {
angular: {
deps: [ 'jquery' ],
exports: 'angular'
},
'angular-boot': {
deps: ['app']
}
}
and than, since you don't need to include the 'app' explicitly your require call can be reduced to:
require(['angular-boot']);
I'm new to require js and i'm using backbone with layout manager. I've pasted my code below and i'm not able to get the layout manager to work and i get this error :
"Uncaught TypeError: Cannot call method 'extend' of undefined"
in line where layoutmanager is used (Backbone.LayoutView.extend)
Main.js
require.config({
paths: {
jquery: 'lib/jquery-1.9.1.min',
underscore: 'lib/underscore-min',
backbone: 'lib/backbone-min',
handlebars: 'lib/handlebars',
layoutManager : 'lib/backbone.layoutmanager'
mousewheel : 'lib/jquery.mousewheel.min'
},
shim : {
'backbone' : {
deps: ['jquery', 'underscore' ],
exports: 'Backbone'
},
'layoutManager' : {
deps: ['jquery', 'underscore', 'backbone'],
exports: 'LayoutManager'
},
'mousewheel' : ['jquery']
}
});
require(["jquery", "underscore", "backbone", "layoutManager", "handlebars","mousewheel", "common"],function($, _, Backbone, LayoutManager, Handlebars,mousewheel, App) {
App.Views.HelloView = Backbone.LayoutView.extend({
template : '#hello_tmpl1',
});
App.Layouts.AppLayout = new BackBone.Layout({
template : '#layout',
views : {
".helloView" : new App.Views.HelloView()
}
});
$('body').empty().append(App.Layouts.AppLayout.el.render());
});
Common.js
define(function(){
var App = null;
App = { Models:{}, Views:{}, Collections:{}, Templates:{}, Router:{}, Layouts:{}};
return App;
});
function($, _, Backbone, LayoutManager
Here you name it LayoutManager.
App.Views.HelloView = Backbone.LayoutView.extend({
Here you try to use it as Backbone.LayoutView... which doesn't exist (thus the undefined). Try
App.Views.HelloView = LayoutView.extend({
The Backbone var you have here is different from the global one, think requirejs :)
New version of layoutmanager doesn't use 'LayoutView' to create views. Use Backbone.Layout.extend({ ...}) to create your views ... have fun .. ;)