Script error in require.js backbone project - backbone.js

I am a new developer with backbone and require.js.
This is the structure of my project :
And this my code :
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="app/script/libs/require.js" data-main="app/script/main.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
This is main.js :
require.config({
paths: {
jquery: 'app/script/libs/jquery/jquery-1.7.1',
underscore: 'app/script/libs/underscore/underscore',
backbone: 'app/script/libs/backbone/backbone'
},
shim: {
backbone: ['jquery', 'underscore']
}
});
require(['app'], function(App){
App.initialize();
});
And then when I browse in the browser, I got this error in the console of firefox :
Error: Script error http://requirejs.org/docs/errors.html#scripterror
[Break On This Error]
...irejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=i;d&&(c.origina...
Anyone can tell me, how this error come please? Thanks.

Your require.config contains folders which dont exist. There are no folders such as backbone, jquery, underscore under the app/libs
Change your require.config to the following
require.config({
paths: {
jquery: 'app/script/libs/jquery-1.7.1',
underscore: 'app/script/libs/underscore',
backbone: 'app/script/libs/backbone'
},
shim: {
backbone: ['jquery', 'underscore']
}
});
require(['app'], function(App){
App.initialize();
});

Related

Uncaught Error: [$injector:nomod] Module 'app' is not available

I am new to angularjs and I am facing this error while i run my test using karma-jasmine
Uncaught Error: [$injector:nomod] Module 'app' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.6.6/$injector/nomod?p0=app
at bower_components/angular/angular.js:2297
describe('LoginController', function () {
beforeEach(module('app'));
var $controller;
beforeEach(inject(function(_$controller_){
$controller = _$controller_;
}));
describe('homeBtn', function () {
it('whether its sign in or register', function () {
var $scope = {};
var controller = $controller('LoginController', { $scope: $scope });
$scope.homeBtn("Register");
expect($scope.signinerror).toBeFalsy();
expect($scope.tryagain).toBeFalsy();
expect($scope.registererror).toBeFalsy();
expect($scope.modal_title).toBe("Register");
});
});
});
this is my app.js
var app = angular.module('app', ['ngRoute','ngWebSocket','ng.epoch']);
This is my Login Controller
angular.module('app').controller('LoginController',['$rootScope','$scope','$location','$http', function($rootScope,$scope,$location,$http){
$scope.homeBtn = function(keyvalue){
$scope.signinerror=false;
$scope.tryagain=false;
$scope.registererror=false;
if(keyvalue == "Register"){
$scope.modal_title="Register";
$scope.reg=true;
}
else{
$scope.reg=false;
$scope.modal_title="Sign In";
}
}
Here is my HTML code
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet"href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="bower_components/epoch/dist/css/epoch.min.css">
<link rel="stylesheet" href="app/css/index.css">
</head>
<body>
<ng-view> </ng-view>
<!--Bower Components-->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/angular-websocket/dist/angular-websocket.min.js"></script>
<script src="bower_components/d3/d3.js"></script>
<script src="bower_components/epoch/dist/js/epoch.min.js"></script>
<script src="bower_components/ng-epoch/ng-epoch.js"></script>
<script src="bower_components/js-md5/src/md5.js"></script>
<!--MainJS-->
<script src="app/js/app.js"></script>
<!--Controllers-->
<script src="app/js/Controllers/LoginController.js"></script>
<script src="app/js/Controllers/HomeController.js"></script>
<!--custom js files-->
<script src="app/js/libraries/common.js"></script>
<script src="app/js/libraries/smoothie.js"></script>
<!--directives-->
<!--factories-->
<script src="app/js/Factories/websocketservice.js"></script>
</body>
</html>
and here is my karma config file
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-resource/angular-resource.js',
'app/**/*.js',
'test/**/*.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}

Angular 2: can not find #angular modules in RC 1 version

I started writing angular2 application with RC1 version. As described in the angular.io docs I created separate system.config.js file in the root.
// system.config.js
(function (global) {
var map = {
'app': 'app',
'rxjs': 'node_modules/rxjs',
'#angular': 'node_modules/#angular'
};
var packages = {
'app': {main: 'main.js', defaultExtension: 'js'},
'rxjs': {defaultExtension: 'js'}
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router'
];
packageNames.forEach(function (pkgName) {
packages[pkgName] = {main: 'index.js', defaultExtension: 'js'};
});
var config = {
map: map,
packages: packages
};
if (global.filterSystemConfig) {
global.filterSystemConfig(config);
}
System.config(config);
})(this);
I have given reference to find #angular modules under node_modules '#angular': 'node_modules/#angular' but it is displaying 404 you can see here. I have bootstrapped it according to the guidelines given in the docs. Here in my app/main.ts file
/*main.ts*/
/// <reference path="../typings/browser/ambient/es6-shim/index.d.ts" />
import {bootstrap} from '#angular2/platform-browser-dynamic/';
import {AppComponent} from './app.component';
bootstrap(AppComponent);
and here is how index.html looks like
<body>
<my-app>Loading...</my-app>
<script src="node_modules/es6-shim/es6-sham.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<!--SystemsJs configuration-->
<script>
System.import('app/main')
.then(null, console.error.bind(console));
</script>
</body>
and I have installed both #angular/core and #angular/platform-browser
Any help would be greatly appreciated!

How to use Require.js with angularjs for lazy load

I am developing the app with angularjs and codeigniter. And I have done with it( DEMO app ), mostly.
What I want to do is: implement lazy loading or don't want to include all these files at start, just include when needed.
Here is my Layout HEAD tag including the required js and css files.
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>UMS : Admin </title>
<!-- added for Angular JS -->
<link href="<?php echo base_url(); ?>angular/css/loading-bar.min.css" rel="stylesheet">
<link href="<?php echo base_url(); ?>angular/css/animation.css" rel="stylesheet">
<link href="<?php echo base_url(); ?>angular/css/angular-chart.css" rel="stylesheet">
<!-- added for Angular JS -->
<!-- Bootstrap Core CSS -->
<link href="<?php echo base_url(); ?>bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- MetisMenu CSS -->
<link href="<?php echo base_url(); ?>bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet">
<!-- Timeline CSS -->
<link href="<?php echo base_url(); ?>dist/css/timeline.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="<?php echo base_url(); ?>dist/css/sb-admin-2.css" rel="stylesheet">
<!-- Morris Charts CSS -->
<link href="<?php echo base_url(); ?>bower_components/morrisjs/morris.css" rel="stylesheet">
<!-- Custom Fonts -->
<link href="<?php echo base_url(); ?>bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<!-- jQuery -->
<script src="<?php echo base_url(); ?>bower_components/jquery/dist/jquery.min.js"></script>
<!-- jQuery -->
<!-- Bootstrap Core JavaScript -->
<script src="<?php echo base_url(); ?>bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Metis Menu Plugin JavaScript -->
<script src="<?php echo base_url(); ?>bower_components/metisMenu/dist/metisMenu.min.js"></script>
<!-- DataTables JavaScript REMOVED -->
<!-- Custom Theme JavaScript -->
<script src="<?php echo base_url(); ?>dist/js/sb-admin-2.js"></script>
<!-------------Angular js------------------->
<script src="<?php echo base_url();?>angular/js/angular.min.js"></script>
<script src="<?php echo base_url();?>angular/js/angular-route.min.js"></script>
<!-- flash msg -->
<script src="<?php echo base_url();?>angular/js/angular-flash.js"></script>
<!-- flash msg -->
<!--loading bar-->
<script src="<?php echo base_url();?>angular/js/loading-bar.min.js"></script>
<script src="<?php echo base_url();?>angular/js/angular-animate.min.js"></script>
<!--loading bar-->
<!-- charts-->
<script src="<?php echo base_url();?>angular/js/chart.min.js"></script>
<script src="<?php echo base_url();?>angular/js/angular-chart.min.js"></script>
<!--[if lt IE 9]><script src="<?php echo base_url();?>angular/js/IE8_9/excanvas.js"></script><![endif]-->
<!--[if lt IE 9]><script src="<?php echo base_url();?>angular/js/IE8_9/es5-shim.js"></script><![endif]-->
<!-- charts-->
<!-- core angular APPLICATION specific -->
<script src="<?php echo base_url();?>angular/js/admin/demo_angular.js"></script>
<script src="<?php echo base_url();?>angular/js/admin/app.js"></script>
<script src="<?php echo base_url();?>angular/js/admin/demo-dropdown-controller.js"></script>
<!-- core angular APPLICATION specific -->
<!--Directives developed by VANESH -->
<script src="<?php echo base_url();?>angular/js/angular-directives.js"></script>
<!--Directives developed by VANESH -->
<!-- ui bootstrap pagination -->
<script src="<?php echo base_url();?>angular/js/ui-bootstrap-tpls-0.12.0.js"></script>
<!-- ui bootstrap pagination -->
<!-------------Angular js------------------->
Here is my app. js (just showing the structure or how i am injecting the dependancies)
/* this is the angular js file for our UMS */
var base_url="http://localhost/ums/";
/* angularapp (asssigned to html tag in view) */
/* angularControllers is module created in demo_angular.js */
var angularapp = angular.module('angularapp', ['ngRoute','angularControllers','flash','angular-loading-bar','ngAnimate','ui.bootstrap','input_match','uniqueField','uniqueEdit','chart.js']);
angularapp.config(['$routeProvider', function($routeProvider){
// routing configuration.......
}]);
Here is another js (demo_angular.js) where i have/had bunhch of controllers named as single module.
var base_url="http://localhost/ums/";
var angularControllers = angular.module('angularControllers', ['flash']);
angularControllers.controller('AddUserCtrl', ['$scope','$http', '$timeout','Flash', function($scope,$http, $timeout,Flash)
{/*...doing stuff...*/}
//other controllers same like above (edit user, all users, delete user, delete users...)
This app is working fine! Just there is need to implement lazy load(that i don't know).
Listen about Require.js.
Main Problem: How to use Require.js in this (my app: mentioned above).
Please do suggest some important with example.
IMPORTANT:
Is there anyone who can guide me (above) app specific? Means how my app.js and demo_angular.js will look like? how my main.js and require.js will look like? NOTE: I am injecting dependancies in app and controllers, dependancies in the sense services, directives, which are constructed or third party
There is a very good example which can help you?
Lazy Loading with Require js and Angualar js
Your main.js will look like
'use strict';
var app = angular.module('app', ['ngRoute']);
require js will look like
require.config({
baseUrl: './scripts/',
urlArgs: 'v=1.1',
waitSeconds: 200,
paths: {
'jquery': './libs/jquery.min',
'jquery-migrate.min': './libs/jquery-migrate.min',
'jquery-ui.min': './libs/jquery-ui.min',
'jquery.mobile.custom.min': './libs/jquery.mobile.custom.min',
'jquery.easyui.min': './libs/jquery.easyui.min',
'angular-resource': './libs/1.3.14/angular-resource.min',
'angular': './libs/1.3.14/angular.min',
'angular-route': './libs/1.3.14/angular-route.min',
'angular-animate': './libs/1.3.14/angular-animate.min',
'bootstrap': './libs/bootstrap',
'toastr': './modules/toastr',
'jsapi': './libs/jsapi',
'ngPopover': './modules/ngPopover',
'angular-file-upload': './modules/angular-file-upload',
'ckeditor': './javascripts/ckeditor4.4.7/ckeditor',
//'ng-infinite-scroll.min': './modules/ng-infinite-scroll.min',
'app': 'app',
'tr': './modules/tr',
'en': './modules/en',
'hi': './modules/hi',
'ru': './modules/ru',
'fr': './modules/fr',
'de': './modules/de',
}
});
require(
{
shim: {
//*************Jquery*****************
'angular-resource': {
deps: ['angular']
},
'angular-route': {
deps: ['angular']
},
'jquery-migrate.min': {
deps: ['jquery']
},
'jquery-ui.min': {
deps: ['jquery',
'jquery-migrate.min']
},
'jquery.easyui.min': {
deps: ['jquery',
'jquery-migrate.min']
},
'libs/shoppingCart': {
deps: ['jquery']
},
//Jquery ends
//************bootstrap**************
'bootstrap': {
deps: ['jquery',
'jquery-migrate.min',
'jquery-ui.min']
},
'javascripts/theme': {
deps: ['jquery', 'jquery-ui.min',
'javascripts/plugins/autosize/jquery.autosize-min',
'javascripts/plugins/charCount/charCount',
'javascripts/plugins/bootstrap_maxlength/bootstrap-maxlength.min',
//'javascripts/plugins/bootstrap_datetimepicker/bootstrap-datetimepicker',
'javascripts/plugins/bootstrap_daterangepicker/bootstrap-daterangepicker',
//'javascripts/plugins/common/bootstrap-wysihtml5',
'javascripts/plugins/nestable/jquery.nestable',
'javascripts/plugins/tabdrop/bootstrap-tabdrop',
//'javascripts/plugins/naked_password/naked_password-0.2.4.min',
'javascripts/plugins/datatables/jquery.dataTables.min',
'javascripts/plugins/datatables/jquery.dataTables.columnFilter',
'javascripts/plugins/bootstrap_colorpicker/bootstrap-colorpicker.min',
'javascripts/plugins/modernizr/modernizr.min']
},
//bootstrap ends
//***********plugins*****************
//'javascripts/plugins/msdropdown/jquery.dd': {
// deps: ['libs/jquery']
//},
'javascripts/plugins/select2/select2': {
deps: ['jquery',
'bootstrap']
},
'javascripts/plugins/timeago/jquery.timeago': {
deps: ['javascripts/theme']
},
'javascripts/plugins/autosize/jquery.autosize-min': {
deps: ['jquery']
},
'javascripts/plugins/charCount/charCount': {
deps: ['jquery']
},
'javascripts/plugins/bootstrap_maxlength/bootstrap-maxlength.min': {
deps: ['jquery']
},
//'javascripts/plugins/common/wysihtml5.min': {
// deps: ['jquery']
//},
//'javascripts/plugins/common/bootstrap-wysihtml5': {
// deps: ['jquery', 'javascripts/plugins/common/wysihtml5.min']
//},
'javascripts/plugins/nestable/jquery.nestable': {
deps: ['jquery']
},
'javascripts/plugins/bootstrap_daterangepicker/bootstrap-daterangepicker': {
deps: ['jquery']
},
'javascripts/plugins/tabdrop/bootstrap-tabdrop': {
deps: ['jquery']
},
'javascripts/plugins/naked_password/naked_password-0.2.4.min': {
deps: ['jquery']
},
'javascripts/plugins/datatables/jquery.dataTables.min': {
deps: ['jquery']
},
'javascripts/plugins/datatables/jquery.dataTables.columnFilter': {
deps: ['jquery']
},
'javascripts/plugins/bootstrap_colorpicker/bootstrap-colorpicker.min': {
deps: ['jquery']
},
'javascripts/plugins/modernizr/modernizr.min': {
deps: ['jquery']
},
'javascripts/plugins/bootbox/bootbox.min': {
deps: ['jquery']
},
'javascripts/plugins/validate/jquery.validate.min': {
deps: ['jquery',
'jquery-ui.min',
'javascripts/theme']
},
'javascripts/plugins/FlowJs/flow': {
deps: ['jquery']
},
'javascripts/plugins/FlowJs/fusty-flow': {
deps: ['jquery',
'javascripts/plugins/FlowJs/flow']
},
'javascripts/plugins/FlowJs/fusty-flow-factory': {
deps: ['jquery']
},
'javascripts/plugins/validate/jquery.validate.min': {
deps: ['bootstrap']
},
'javascripts/plugins/validate/additional-methods': {
deps: ['javascripts/plugins/validate/jquery.validate.min']
},
'javascripts/JsCookies': {
deps: ['jquery']
},
'ckeditor' : {
deps: ['jquery']
},
//plugins end
//***********modules*****************
'modules/resettableForm': {
deps: ['angular']
},
'toastr': {
deps: ['jquery-migrate.min']
},
'modules/resettableForm': {
deps: ['angular',
'toastr']
},
'modules/angular-gettext': {
deps: ['angular']
},
'modules/angular-multi-select': {
deps: ['app']
},
'modules/common': {
deps: ['angular',
'toastr']
},
'modules/logger': {
deps: ['angular',
'modules/common']
},
'modules/ui-bootstrap-tpls-0.9.0': {
deps: ['angular',
'toastr']
},
'modules/bootstrap.dialog': {
deps: ['angular',
'modules/ui-bootstrap-tpls-0.9.0',
'modules/common']
},
'modules/translations': {
deps: ['app']
},
'modules/loading-bar': {
deps: ['app']
},
'angular-file-upload': {
deps: ['angular', 'toastr']
},
//'ng-infinite-scroll.min': {
// deps: ['angular']
//},
'ngPopover': {
deps: ['app']
},
//'modules/SharedServices': {
// deps: ['app']
//},
'modules/ng-flow': {
deps: ['app',
'angular']
},
'en': {
deps: ['app']
},
'fr': {
deps: ['app']
},
'de': {
deps: ['app']
},
'hi': {
deps: ['app']
},
//'modules/tr': {
// deps: ['app']
//},
'ru': {
deps: ['app']
},
'modules/paypalfactory': {
deps: ['app']
},
'angular-animate': {
deps: ['app']
},
//'modules/ngAutocomplete': {
// deps: ['app']
//},
'modules/bootstrap-select.min': {
deps: ['app']
},
//modules end
//***********Angular Common*****************
'app': {
deps: ['angular',
'angular-route',
'angular-resource',
'libs/Base64',
'libs/moment',
'modules/common',
'angular-file-upload']//,
//'modules/ngAutocomplete']
},
'routes': {
deps: ['app']
},
//Angular Common ends
//***********Angular Controllers***********
'controllers/manageEbayScheduledInventoryController': {
deps: ['app']
},
'jsapi': {
deps: ['app']
},
//'controllers/googleChartController': {
// deps: ['app', 'libs/jsapi']
//},
//Angular Controller ends
//***********Angular Services*************
'services/manageEbayScheduledInventoryService': {
deps: ['app']
},
//Angular Utility Services Ends
//Angular Filters
'filters/ellipsis': {
deps: ['app']
},
//Angular Filters ends
//Angular Directives
'directives/passwordValidate': {
deps: ['app']
},
}
},
// Including all of the modules to allow concencation and minification for deployment
[
//*************Jquery*****************'
'jquery', 'libs/moment', 'jquery.easyui.min',
//Jquery ends
//************bootstrap**************
'bootstrap', 'javascripts/theme', 'libs/shoppingCart',
//bootstrap ends
//***********plugins*****************
/*'javascripts/plugins/msdropdown/jquery.dd',*/ 'javascripts/plugins/select2/select2', 'javascripts/JsCookies', 'javascripts/plugins/bootbox/bootbox.min',
'javascripts/plugins/FlowJs/flow', 'javascripts/plugins/FlowJs/fusty-flow', 'javascripts/plugins/FlowJs/fusty-flow-factory',
'javascripts/plugins/validate/jquery.validate.min', 'javascripts/plugins/timeago/jquery.timeago','ckeditor',
//plugins end
//***********modules*****************
'toastr', 'modules/resettableForm', 'modules/angular-gettext', 'modules/angular-multi-select', 'modules/common', 'modules/logger',
'modules/ui-bootstrap-tpls-0.9.0', 'modules/bootstrap.dialog', 'modules/translations', 'ngPopover', //'modules/SharedServices',
'modules/ng-flow', 'en', 'de', 'fr', 'hi', 'ru', //'modules/tr',
'modules/paypalfactory', 'modules/loading-bar', 'angular-animate', 'modules/bootstrap-select.min', 'angular-file-upload', //'ng-infinite-scroll.min', //'modules/ngAutocomplete',
//modules end
//***********Angular Common*****************
'app', 'routes', 'jsapi',
//Angular Common ends
//***********Angular Controllers***********'controllers/supplierController',
'controllers/manageEbayScheduledInventoryController',
//Angular Controller ends
//***********Angular Services*************'services/supplierService','services/uploadManagerService','services/createPurchaseOrderService',
'services/manageEbayScheduledInventoryService',
//Angular Services ends
//Angular Utility Services Starts
'services/sortingService',
//Angular Utility Services Ends
//Angular filters
'filters/ellipsis', 'filters/currency',
//Angular filters ends
//Angular Directive
'directives/passwordValidate', 'directives/focus', 'directives/mypopover', 'directives/priceBox', 'directives/onDragStart'
],
function () {
angular.bootstrap(document, ['app']);
}
);
In reuire.js you can find how dependecy is working
'javascripts/plugins/timeago/jquery.timeago': {
deps: ['javascripts/theme']
},
Here javascripts/plugins/timeago/jquery.timeago depends on 'javascripts/theme'
You can refer this link also it is a very good example

Angular and Grunt

I'm a Grunt newbie and I'm trying to convert an Angular app (based on angular-seed) to use it for CSS/JS concat/minification. I have an index.html file that defines the CSS and JS files:
<!-- build:css css/myjmh.css -->
<link rel="stylesheet" href="lib/bootstrap/bootstrap.min.css"/>
<link rel="stylesheet" href="lib/font-awesome/font-awesome.min.css"/>
<link rel="stylesheet" href="lib/toaster/toaster.css"/>
<link rel="stylesheet" href="css/app.css"/>
<link rel="stylesheet" href="css/custom.css"/>
<link rel="stylesheet" href="css/responsive.css"/>
<!-- endbuild -->
...
<!-- build:js js/myjmh.min.js -->
<script src="lib/jquery/jquery-1.10.2.min.js"></script>
<script src="lib/bootstrap/bootstrap.min.js"></script>
<script src="lib/angular/angular.min.js"></script>
<script src="lib/angular/angular-animate.min.js"></script>
<script src="lib/angular/angular-cookies.min.js"></script>
<script src="lib/angular/angular-resource.min.js"></script>
<script src="lib/angular/angular-route.min.js"></script>
<script src="lib/fastclick.min.js"></script>
<script src="lib/toaster/toaster.js"></script>
<script src="lib/webshim/modernizr.min.js"></script>
<script src="lib/webshim/polyfiller.min.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
<!-- endbuild -->
I'm trying to use grunt-usemin and its useminPrepare task to grab these values from my HTML.
Here's my Gruntfile.js:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: ["dist"],
copy: {
main: {
src: 'app/index.html',
dest: 'dist/index.html'
}
},
useminPrepare: {
html: 'app/index.html'
},
usemin: {
html: ['dist/index.html']
},
ngmin: {
dist: {
files: [
{
expand: true,
cwd: '.tmp/concat/js',
src: '*.js',
dest: '.tmp/concat/js'
}
]
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-ngmin');
grunt.loadNpmTasks('grunt-usemin');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', [
'copy', 'useminPrepare', 'concat', 'ngmin', 'uglify', 'cssmin', 'usemin'
]);
};
With all these settings, a "dist" directory is created with all the artifacts and everything seems to be generated/concatenated and minified correctly. However, when I load the new page up in my browser, I get the following error:
Uncaught Error: [$injector:unpr] http://errors.angularjs.org/1.2.3/$injector/unpr?p0=aProvider%20%3C-%20a
It seems like Grunt is doing something that doesn't play well with Angular. Any ideas on what this might be?
I was able to solve this by turning off mangling in uglify:
uglify: {
options: {
report: 'min',
mangle: false
}
}
As you might notice from my Gruntfile.js, ngmin is already used and this doesn't seem to help.
Found answer here: https://stackoverflow.com/a/17239358/65681
You need to do one of two things:
Make all of your angular code minification-friendly. See: http://docs.angularjs.org/guide/di#dependency-injection_dependency-annotation
Use a tool like grunt-ngannotate
If you are having same issues with declarations as I had, you could also use ng-annotate in order to achieve this. Here is a link to github: https://github.com/mzgol/grunt-ng-annotate
My working configuration is:
ngAnnotate: {
options: {
singleQuotes: true,
regexp: '^(ng\n?[\\ ]+(.*)|(module.*))$'
},
prod: {
files: [{
expand: true,
src: 'dist/**/*.js'
}]
}
}
Use it carefully as it will modify existing files. My assumption is that files in 'dist' folder should be generated by Grunt and can be deleted at any time.
As others have stated, it seems that you have a problem with minification. I see that you're using ngmin. But ngmin may not work when a file with mixed patterns is thrown at it. I mean, make sure that all of the files that you pass to ngmin don't already have minification-safe pattern.
Mangle false shouldn't be the solution, actually the code is not minification friendly, but the issues that I had were not explicitly described here, so they were:
1) "Make sure you only define each module with the angular.module(name, [requires]) syntax once across your entire project. Retrieve it for subsequent use with angular.module(name)" - I used it wrong in many places and it worked with mangle:false, breaking when setting mangle:true
2) I used bootstrap modal windows specifying instance controller not as a string, I've found the solution here

How to do multiple models in the same page using backbone and RequireJS

I am developing an aplication single page. I'm using Backbone.js and RequireJS.
The problem is that on one page I use 3 different models that are not interrelated. But always only loads the first.
page.html
<html><heade></heade><body>
<div id="content">
<div id="results"></div>
<div id="collectorTable">
<!-- the container that gets populated with the index -->
</div>
<div id="collectorEdition">
<!-- the container that gets populated with the edition -->
</div>
<div style="margin-top: 10px">
<div id="terms" style="width: 50%; float: left; height: auto !important; min-height: 100px;">
<div id="termTable"><!-- Term model index --></div>
<div id="termEdition"><!-- Term model edition --></div>
</div>
<div id="termsCampaign" style="width: 50%; float: left; height: auto !important; min-height: 100px;">
<div id="termCampaignTable"><!-- TermCampaign model edition --></div>
<div id="termCampaignEdition"><!-- TermCampaign model edition --></div>
</div>
</div>
</div>
<script data-main="js/mainCollector" src="js/libs/require.js"></script>
<script data-main="js/mainTerm" src="js/libs/require.js"></script>
<script data-main="js/mainTermCampaign" src="js/libs/require.js"></script>
</body>
</html>
mainCollector.js
require.config({
baseUrl: "js",
paths: {
html5shiv: "libs/html5shiv",
jquery: "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min",
jqueryui: "http://code.jquery.com/ui/1.10.3/jquery-ui",
tablesorter: "libs/jquery.tablesorter.min",
script: "script",
underscore: "libs/underscore.min",
backbone: "libs/backbone.min",
utils: "utils",
//Files Collector
CollectorModel: "models/CollectorModel",
CollectorCollection: "collections/CollectorCollection",
CollectorRouter: "routers/CollectorRouter",
// Views
edit: "views/Collector/Collector_edit",
index: "views/Collector/Collector_index",
neww: "views/Collector/Collector_new",
row: "views/Collector/Collector_row",
show: "views/Collector/Collector_show",
//Templates
'templates': 'templates'
},
shim: {
jqueryui: {
deps: ["jquery"]
},
tablesorter: {
deps: ["jquery"],
exports: "TableSorter"
},
script: {
deps: ["jquery", "jqueryui", "tablesorter"],
exports: "Script"
},
underscore: {
exports: "_"
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
}
}
});
require(["backbone", "underscore", "CollectorCollection", "CollectorRouter", "script"],
function (Backbone, _, CollectorCollection, CollectorRouter) {
var Collectors = new CollectorCollection();
var router = new CollectorRouter({Collectors: Collectors});
Backbone.history.start();
});
mainTerm.js
require.config({
baseUrl: "js",
paths: {
html5shiv: "libs/html5shiv",
jquery: "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min",
jqueryui: "http://code.jquery.com/ui/1.10.3/jquery-ui",
tablesorter: "libs/jquery.tablesorter.min",
script: "script",
underscore: "libs/underscore.min",
backbone: "libs/backbone.min",
utils: "utils",
//Files Term
termModel: "models/termModel",
termCollection: "collections/termCollection",
termRouter: "routers/termRouter",
// Views
...
//Templates
'templates': 'templates'
},
shim: {
...
}
});
require(["backbone", "underscore", "termCollection", "termRouter", "script"],
function (Backbone, _, TermCollection, TermRouter) {
var terms = new TermCollection();
var router = new TermRouter({terms: terms});
Backbone.history.start();
});
mainTermCampaign.js
require.config({
baseUrl: "js",
paths: {
html5shiv: "libs/html5shiv",
jquery: "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min",
jqueryui: "http://code.jquery.com/ui/1.10.3/jquery-ui",
tablesorter: "libs/jquery.tablesorter.min",
script: "script",
underscore: "libs/underscore.min",
backbone: "libs/backbone.min",
utils: "utils",
//Files Term Campaign
termCampaignModel: "models/termCampaignModel",
termCampaignCollection: "collections/termCampaignCollection",
termCampaignRouter: "routers/termCampaignRouter",
// Views
...
//Templates
'templates': 'templates'
},
shim: {
...
}
});
require(["backbone", "underscore", "termCampaignCollection", "termCampaignRouter", "script"],
function (Backbone, _, TermCampaignCollection, TermCampaignRouter) {
var termsCampaign = new TermCampaignCollection();
var router = new TermCampaignRouter({termsCampaign: termsCampaign});
Backbone.history.start();
});
You should have only one main.js file in a view, so
<script data-main="js/mainCollector" src="js/libs/require.js"></script>
<script data-main="js/mainTerm" src="js/libs/require.js"></script>
<script data-main="js/mainTermCampaign" src="js/libs/require.js"></script>
is wrong, use:
<script data-main="js/main" src="js/libs/require.js"></script>
, and put the logic into that main.js file. You wrote that mainCollector, mainTerm.js and mainTermCampaign.js are similar. which mean you have three routers in your app, which also seems like a bad thing, I think one should be enough. I think you should think again how to structure your code.
You put the script tag into your body, which is also unusual, read require.js docs and try to use best practices.
Solved
index.html
<html>
<heade>
<script data-main="js/main" src="js/libs/require.js"></script>
</head>
<body>
.....
</body>
</html>
main.js
require.config({
baseUrl: "js",
paths: {
html5shiv: "libs/html5shiv",
jquery: "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min",
jqueryui: "http://code.jquery.com/ui/1.10.3/jquery-ui",
tablesorter: "libs/jquery.tablesorter.min",
script: "script",
underscore: "libs/underscore.min",
backbone: "libs/backbone.min",
utils: "helpers/utils",
//Files Collector
CollectorModel: "models/CollectorModel",
CollectorCollection: "collections/CollectorCollection",
// Files Term
TermModel: "models/TermModel",
TermCollection: "collections/TermCollection",
// Files Term Campaign
TermCampaignModel: "models/TermCampaignModel",
TermCampaignCollection: "collections/TermCampaignCollection",
// Router
Router: "routers/Router",
// Views Collector
editCollector: "views/Collector/Collector_edit",
indexCollector: "views/Collector/Collector_index",
newCollector: "views/Collector/Collector_new",
rowCollector: "views/Collector/Collector_row",
showCollector: "views/Collector/Collector_show",
//Views Term
editTerm: "views/Term/Term_edit",
indexTerm: "views/Term/Term_index",
newTerm: "views/Term/Term_new",
rowTerm: "views/Term/Term_row",
showTerm: "views/Term/Term_show",
//Views Term Campaign
editTermCampaign: "views/TermCampaign/TermCampaign_edit",
indexTermCampaign: "views/TermCampaign/TermCampaign_index",
newTermCampaign: "views/TermCampaign/TermCampaign_new",
rowTermCampaign: "views/TermCampaign/TermCampaign_row",
showTermCampaign: "views/TermCampaign/TermCampaign_show",
//Templates
'templates': 'templates'
},
shim: {
jqueryui: {
deps: ["jquery"]
},
tablesorter: {
deps: ["jquery"],
exports: "TableSorter"
},
script: {
deps: ["jquery", "jqueryui", "tablesorter"],
exports: "Script"
},
underscore: {
exports: "_"
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
}
}
});
require(["backbone", "underscore", "CollectorCollection", "TermCollection", "TermCampaignCollection", "Router", "script"],
function (Backbone, _, CollectorCollection, TermCollection, TermCampaignCollection, Router) {
var Collectors = new CollectorCollection();
var Terms = new TermCollection();
var TermsCampaign = new TermCampaignCollection();
var router = new Router({Collectors: Collectors, Terms: Terms, TermsCampaign: TermsCampaign});
Backbone.history.start();
});
router.js
define([
"backbone",
"CollectorModel", "editCollector", "indexCollector", "newCollector", "showCollector",
"TermModel", "editTerm", "indexTerm", "newTerm", "showTerm",
"TermCampaignModel", "editTermCampaign", "indexTermCampaign", "newTermCampaign", "showTermCampaign"
],
function(_,
CollectorModel,CollectorEditView, CollectorIndexView, CollectorNewView, CollectorShowView,
TermModel, TermEditView, TermIndexView, TermNewView, TermShowView,
TermCampaignModel, TermCampaignEditView, TermCampaignIndexView, TermCampaignNewView, TermCampaignShowView
){
var Router = Backbone.Router.extend({
routes: {
// Collector
"Collector/new": "createCollector",
"Collectors/index": "indexCollector",
"Collector/:id/edit": "editCollector",
"Collector/:id/view": "showCollector",
// Term
"Term/new": "createTerm",
"Terms/index": "indexTerm",
"Term/:id/edit": "editTerm",
"Term/:id/view": "showTerm",
// Term Campaign
"TermCampaign/new": "createTermCampaign",
"TermsCampaign/index": "indexTermCampaign",
"TermCampaign/:id/edit": "editTermCampaign",
"TermCampaign/:id/view": "showTermCampaign"
},
// functions ...
});
return Router;
});

Resources