RequireJS configuration error - jQuery not found when calling Backbone - backbone.js

I'm trying to setup a require js project for learning purposes. I need to run a Backbone app.
Index.html, looks plain and simple:
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>RequireJS - Test drive</title>
<!-- data-main attribute tells require.js to load scripts/main.js after
require.js loads. -->
<script data-main="js/main" src="js/vendor/require.js"></script>
</head>
<body>
<h1>RequireJS - Test drive</h1>
</body>
</html>
Currently I have this config in my main.js: (which is the entry point in index.html for requirejs)
require.config({
paths: {
underscore: 'vendor/underscore-1.9.1.min',
jquery: 'vendor/jquery-3.4.1.min',
backbone: 'vendor/backbone-1.4.0.min',
app: 'app/app',
userModel: 'app/models/user.model',
userListView: 'app/views/user-list.view',
userSingleView: 'app/views/user-single.view',
},
bundles: {
'models': ['userModel']
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
}
},
});
// Start the app
define(['app'], (App) => {
return App.initialize();
});
In app.js, which I try to initiate the app with, I have the following:
define(['backbone'], (Backbone) => {
const initialize = () => {
console.log('App initialized.', Backbone);
const data = {title: 'title'};
const view = 0; // new View here....
};
return {
initialize: initialize
}
});
Now, if I remove backbone as a dependency, I am able to see the console.log message in the browser. If I leave it there, then the console throws this error:
require.js:5 GET http://127.0.0.1:8080/js/js/vendor/jquery-3.4.1.min.js net::ERR_ABORTED 404 (Not
Found)
require.js:5 Uncaught Error: Script error for "js/vendor/jquery-3.4.1.min", needed by: backbone
https://requirejs.org/docs/errors.html#scripterror
at makeError (require.js:5)
at HTMLScriptElement.onScriptError (require.js:5)
Inspecting the network tab, I can see that the jQuery dependency has errored out, and for some reason an additional /js has been added to the path, which results in a 404 error for jQuery, but only when I try to use Backbone on the app.js file.
Path looks like this, with the additional /js added to it:
http://127.0.0.1:8080/js/js/vendor/jquery-3.4.1.min.js
What is it that I am missing in the configuration/setup of the application?

I believe you should set baseUrl in your config
require.config({
baseUrl: '/js'
});

Related

AngularJS + RequireJS application never runs the controller

EDIT As far as I understood through further research AngularJS isn't capable of injecting that controller code the way I wanted it to do. Anyway, I'm still interested in why exactly doesn't it work and how should it be done.
I've been trying to create my own AngularJS + RequireJS project seed and I've run into issues with app modules loading (I see them in the network inspector) but never actually executing.
So I've stripped down the app to just the AngularJS library with basic dependencies handled through in RequireJS and I've noticed that the app loads all of the files and modules properly but the top level application module controller (and now the only module in the app itself) that I'm bootstrapping onto the document never executes. Using ng-inspector I've come to a conclusion that there's also no controller scope defined.
There are no errors whatsoever in the console and what I can confirm is that app bootstraps properly and loads all of the modules but the appController is never executed.
Here's the code of the appBootstrap.js:
//requirejs config
require.config({
baseUrl: '/',
paths: {
'lib' : 'scripts/lib/',
'angular' : 'vendor/angular/angular.min'
},
shim: {
'angular': {
exports: 'angular'
}
}
});
//the actual app bootstrapping
require(['lib/appVendorLibs'], function(){
require([
'lib/appModule'
], function(appModule) {
angular.bootstrap(document, [appModule.name]);
});
});
Here's the appVendorLibs.js:
define([
'angular'
], function() {});
And here's the barebones appModule.js that I've come up with in order to test the controller execution that fails:
define([
'angular',
'lib/appController'
], function(angular, appController) {
var app = angular.module('app', []);
app.controller('appController', appController);
return app;
});
Here's the appController.js:
define([], function() {
var appController = function($scope, $rootScope){
$rootScope.aTestVar = "OK";
$scope.testObject = {};
$scope.testObject.text = "OK";
console.log("OK");
};
return ['$scope', '$rootScope', appController];
});
That console.log() call is never occurs nor do those lines referencing the $rootScope and $scope do anything.
Also, I've got ng-bind in my index.html that should be displaying the testObject.text variable but that never happens.
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="/styles/styles.css"/>
<title>AngularJS Module Loading Seed</title>
<base href="/">
</head>
<body>
<!-- Main Content Container -->
<p ng-bind="testObject.text"></p>
<script src="/vendor/requirejs/require.js" data-main="/scripts/lib/appBootstrap.js"></script>
</body>
</html>
What could be the problem here?

Angular rotue provider not working with Require JS

I'm fairly new to Angular JS.
I was doing some practice demos with require JS along with angular routing using route provider in a well defined folder structure.
I tried searching for similar angular router problems but most do not have any folder structure, Their code was present in script tags.
I hope somebody has the patience to have a quick look and checkout why the route provider seems so non functional despite everything seeming to be done correct. :)
Anyway,
I have an index.html that simply loads the require JS with a source
Index.html
<!DOCTYPE html>
<html>
<head>
<title>MyApp</title>
<meta charset="utf-8"/>
<script data-main="assets/require/requireConfig" src="assets/vendor/require.js"></script>
<link rel="stylesheet" href="assets/css/site.css">
</head>
<body>
<ng-view></ng-view>
</body>
</html>
The Require JS source looks as follows where 'router' is the standard angular-router.
'myApp' would be the app I'm going to bootstrap.
The data source of Require JS
requirejs.config({
baseUrl: 'assets',
paths: {
'myApp': 'require/myApp',
'angular': 'vendor/angular',
'router': 'vendor/angular-route',
'domReady': 'vendor/dom-ready'
},
//Shim is also used to specify if one module must be loaded only after another
//angular does not support AMD out of the box, put it in a shim
shim: {
'angular': {
exports: 'angular'
},
'router': {
deps: ['angular'],
exports: 'router'
}
},
// kick start application
// The ./ represents the base URL given at the top
deps: ['./require/startup']
});
So Now I'm going to run the startup.js to bootstrap my app file
The following is how my startup.js looks
Angular Bootstrapping
define([
'require',
'angular',
'myApp'
], function (require, angular) {
'use strict';
require(['domReady!'], function (document) {
angular.bootstrap(document, ['myApp']);
});
});
And finally....
The Route Provider that is causing all the problems is defined in myApp.js
define(['angular','router'], function (angular) {
'use strict';
var myApp = angular.module('myApp', ["ngRoute"]);
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/login', {
templateUrl: '../../modules/login/login.html'
});
$routeProvider.when('/home', {
templateUrl: '../../modules/home/homepage.html'
});
}]);
});
Ok, So I run the application on an nginx server.
http://localhost/login
OR
http://localhost/home
does not direct me to the required pages I have specified in the templates.
However
If I specify a "$routeProvider.otherwise" it always redirects to it.
If I change $routeProvider.when("/login") to
$routeProvider.when("/"), The router opens up the login page but
complains there is no controller associated with the view specified.
(Hence my conclusion that the template URLs were pointing correctly)
Deciding to create a controller 'loginController' throws the error that the 'controller is not registered'. For which when I digged around that is due to bootstrapping. (Wha?. So whats good about requireJS? But I'll leave that question for another time)
So, why such weird behavior by the route provider?
I do not see it?

Require and Angular RouteProvider undefined

I get undefined in the following code when trying to load via require.js
HTML
<script data-main="application/main" src="http://requirejs.org/docs/release/2.1.14/minified/require.js"></script>
main.js
require.config({
baseUrl: "application",
paths: {
angular: 'https://code.angularjs.org/1.4.5/angular',
angularRoute: 'https://code.angularjs.org/1.4.5/angular-route'
},
shim: {
angular: {exports: 'angular' } ,
angularRoute: { deps: ['angular'], exports: 'angularRoute' },
}
});
require(['app', 'routesBoot'], function (app) {
app.init();
});
app.js
define(['angular'], function (angular) {
var app = angular.module('reporterdashboard', []);
app.init = function () {
console.log('app.init called');
angular.bootstrap(document, ['reporterdashboard']);
};
return app;
});
routesBoot.js
require(['app', 'angularRoute'], function (app, angularRouterParam) {
//put my routes in here, using angularRouterParam
//but angularRouterParam = undefined
return app.config(function (angularRouterParam) {
angularRouterParam.when('/page2', { controller: 'Page2Controller', templateUrl: 'page2.html' });
});
});
When I inspect angularRouterParam passed into routesBoot it's undefined. What have I done wrong ?
I'm basically trying to split my app and therefore, placing my routes in their own file (controllers, directives etc will live in their own boot .js files). I'm letting require.js look after all my .js file loading as can be seen in main.js.
The code in routesBoot is not syntactically correct at the moment as I'm stuck with the problem of an undefined angularRouterParam
The problem was out side of the code I've posted here. I was loading a directive first into the index.html (View First). This directive was loading other dependencies. The project is quite large, some 40 .js files. My restructuring with require was at fault.

No module and Modernizr error when adding angular to requirejs

Im trying to add AngularJS to my web application which already makes use of RequireJS. When loading my test page, i am seeing:
1) Error: No module: MyApp
...),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$prov...
2) TypeError: Modernizr is undefined
if (!Modernizr.history) {
I am using AngularJS v1.1.5
Here's my tree:
resources
- CSS
- js
- controllers
- MainController.js
- libs
- angular.js
- jquery.js
- require.js
- mondernizr.js
......
......
......
main.js
mainApp.js
pages
test.html
main.js
(function(require) {
'use strict';
require.config({
baseUrl: '/resources/js',
paths: {
'zepto' : 'libs/zepto',
'jquery' : 'libs/jquery',
'angular' : 'libs/angular',
'router' : 'libs/page',
'history' : 'libs/history.iegte8',
'event' : 'libs/eventemitter2'
},
shim: {
'zepto' : { exports: '$' },
'angular' : { exports : 'angular' },
'router' : { exports: 'page'},
'modernizr' : { exports: 'Modernizr' }
}
});
require([ 'jquery', 'angular', 'routes', 'modernizr', 'event' ], function($, angular, routes, Modernizr, Event) {
function bootstrap() {
var app = new Event(),
router = routes(app);
if (typeof console !== 'undefined') console.info('>> module routes loaded ... executing router');
router({ click: false, popstate: false });
if (typeof console !== 'undefined') console.info('>> executed router');
}
$(function() {
if (!Modernizr.history) {
require([ 'history' ], bootstrap);
require([ 'controllers/MainController' ], bootstrap);
} else {
require([ 'controllers/MainController' ], bootstrap);
bootstrap();
}
});
});
})(this.require);
mainApp.js
define(['angular'], function(angular) {
return angular.module('MyApp', []);
})
MainController.js
require(['mainApp'], function(mainApp) {
mainApp.controller('MainController', function($scope) {
$scope.data = {message: "Hello"};
})
});
test.html
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<script src="/assets/js/vendor/require.js" data-main="/assets/js/main"></script>
</head>
<body>
<div ng-controller="MainController">
{{ data.message + " world" }}
</div>
</body>
</html>
Any help appreciated.
The No module: MyApp problem is causes by the Angular automatic initialization: <html ng-app="MyApp">. Angular loads before mainApp.js, sees the ng-app and tries to find a module which is not (yet) there.
The solution is to manually bootstrap Angular from within main.js and inside the document load event, as described here.
I am not sure about the problem with Modernizr; I guess you are NOT loading it at all. RequireJs is not complaining because of the shim. How are you loading it? It is not included in your paths configuration. You may want to load Modernizr as independent script before all other scripts (as per recommendations), in which case no paths configuration is needed and the shim is enough.

requirejs with backbone compatibility

The setup below is the only way I can get backbone to ply nice with requirejs - is there a cleaner way? without having to specify the entire path to backbone everytime?
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!doctype html>
<html lang="en">
<head>
<title></title>
<link href='<c:url value="/resources/css/bootstrap.min.css"/>'
rel="stylesheet" type="text/css" />
<script data-main="resources/js/main.js" src="resources/js/lib/require.js"></script>
</head>
<body>
<ul class="nav">
<li >Home</li>
<li>Rentals
<li>Films</li>
</ul>
</body>
</html>
main.js
require.config({
baseUrl : '/sakila/resources/js',
paths : {
jquery : 'lib/jquery-1.8.3.min',
underscore : 'lib/underscore-min',
jqueryui : 'lib/jquery-ui-1.9.2.custom.min'
},
shim : {
'/sakila/resources/js/lib/backbone-min.js' : {
deps : [ 'underscore', 'jquery' ],
exports : 'Backbone'
}
}
});
require([ 'router' ], function(Router) {
Router.initialize();
});
router.js
define(['underscore','jquery','/sakila/resources/js/lib/backbone-min.js'],function(_,$,Backbone){
var AppRouter = Backbone.Router.extend({
routes : {
'home' : 'home',
'films' : 'films',
'rentals' : 'rentals',
'*actions' : 'home', // default action
'':'home'
},
home:function(){
console.log('Routed to home');
},
films:function(){
console.log('Routed to films');
},
rentals:function(){
console.log('Routed to rentals');
},
});
initialize = function() {
var app_router = new AppRouter();
Backbone.history.start();
console.log('history started');
};
return {initialize:initialize};
});
You can create an alias for Backbone in the paths of your requirejs configuration and use that alias in your shims. Also, you don't need to specify the full path for backbone as it respects the baseUrl option in your configuration.
require.config({
baseUrl : '/sakila/resources/js',
paths : {
jquery : 'lib/jquery-1.8.3.min',
underscore : 'lib/underscore-min',
jqueryui : 'lib/jquery-ui-1.9.2.custom.min',
backbone : 'lib/backbone-min'
},
shim : {
backbone : {
deps : [ 'underscore', 'jquery' ],
exports : 'Backbone'
}
}
});
And then use it cleanly elsewhere.
define(['underscore','jquery','backbone'],function(_,$,Backbone){
})
The following post describes how to use Require.js with Backbone.js. It covers 2 different ways of integrating Backbone.js with Require.js that includes shims and AMD compliant backbone.js.
Personally, I would rather use the AMD compliant version of Backbone.js and undescore.js. It makes the configuration a little cleaner and will load the modules in parallel. The folloing blog post describes this option.
Re-Learning Backbone.js – Require.js and AMD

Resources