How do I load precompiled Handlebar templates with Require.js? - requirejs

My precompiled template file is templates.js -- how do I load this file using RequireJS?
requirejs.config({
paths: {
jquery: '../bower_components/jquery/jquery'
, underscore: '../bower_components/underscore/underscore'
, handlebars: '../bower_components/handlebars/handlebars'
, moment: '../bower_components/momentjs/moment'
, spin: '../bower_components/spinjs/spin'
, templates: 'templates'
},
shim: {
handlebars: {
exports: 'Handlebars'
},
templates: {
deps: ['handlebars']
}
}
});
requirejs(["jquery", "underscore", "handlebars", "templates", "moment", "spin", "test"], function($, _, Handlebars, Templates, moment, Spinner, test) {
test.init();
});

You should compile your templates with AMD support . ( I usually do it with help of this Grunt plugin .)
requirejs.config({
paths: {
jquery: '../bower_components/jquery/jquery'
, underscore: '../bower_components/underscore/underscore'
, handlebars: '../bower_components/handlebars/handlebars'
, moment: '../bower_components/momentjs/moment'
, spin: '../bower_components/spinjs/spin'
, templates: 'templates'
},
shim: {
handlebars: {
exports: 'Handlebars'
}
}
});
requirejs(["jquery", "underscore", "templates", "moment", "spin", "test"]
, function($, _, Templates, moment, Spinner, test) {
test.init();
});
Now Templates is an object whose keys are the names of the templates and whose values are the Handlebars templating functions .
Usage example :
var template = Templates['templates/posts.hbs'];
document.body.innerHTML = template({
title: 'All posts',
posts: [
{ title: 'First post', '13/11/2013'},
{ title: 'Second post', '15/11/2013'}
]
});

Related

"define is not defined" - jasmine-node requirejs in Nodejs

I am trying to run jasmine tests on files that are using requirejs. I have a require.config.js file which provides all the configuration for the requirejs and I am passing to this command to run the jasmine test.
jasmine-node --runWithRequireJs --captureExceptions --requireJsSetup spec/require.config.js spec/modules/test.spec.js
My require.config.js looks like this -
var require = {
baseUrl: "../app",
urlArgs: 'cb=' + Math.random(),
paths: {
jquery: '../assets/js/libs/jquery-1.8.2',
underscore: '../assets/js/libs/underscore-min',
backbone: '../assets/js/libs/backbone-min',
jasmine: '../spec/lib/jasmine',
jasminehtml: '../spec/lib/jasmine-html',
boot: '../spec/lib/boot',
spec: '../spec/',
handlebars : '../assets/js/libs/handlebars-1.0.0.beta.6',
// plugins
jqueryui : '../assets/js/plugins/jquery-ui',
jqgrid : '../assets/js/plugins/jqGrid',
jqgridlocale : '../assets/js/plugins/i18n/grid.locale-en',
jqform : '../assets/js/plugins/jquery.form',
jqfiledownload : '../assets/js/plugins/jquery.fileDownload',
migrate: '../assets/js/plugins/jquery-migrate',
text : '../assets/js/plugins/text'
},
shim: {
'underscore': {
exports: "_"
},
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'jasmine': {
exports: 'jasmine'
},
'jasminehtml': {
deps: ['jasmine'],
exports: 'jasmine'
},
'boot': {
deps: ['jasmine', 'jasminehtml'],
exports: 'window.jasmineRequire'
},
'handlebars' : {
exports : 'Handlebars'
},
'text' : {
exports : 'text'
},
'jqueryui' : [ 'jquery' ],
'jqgrid' : [ 'jquery' ],
'jqgridlocale' : [ 'jquery' ],
'jqform':['jquery'],
'jqfiledownload':['jquery'],
'migrate':['jquery']
}};
And my test.spec.js file looks like this -
define(['modules/models/RouteModel','modules/models/RestWebService'], function(RouteModel,RestWebService){
describe("RouteModel :", function(){
it("should create an test instance", function(){
expect(RouteModel).not.toBe(null);
});
});
After running the command I am getting in the console
ReferenceError: define is not defined at C:\Users\TestProject\spec\modules\test.spec.js:1:1
What can be the problem in this case? Is this a path configuration issue?
P.S. - I want complete console output of jasmine, not browser output in jasmine.
Error is pretty much straight forward you need to load requirejs before calling it's function. you can find more clear idea from below link:
https://stackoverflow.com/a/29317859/1607130

How to optimize large js app with r.js optimizer + load libs like jquery, bootstrap from a CDN?

We have built a huge backbone-marionette application with a lot of different libraries (bootstrap, gmaps, momentjs etc.). Everything works like charm when I combine everything into a single even in production mode. To improve the performance most of the libraries should be loaded from a CDN now.
But this seems not be as easy as expected. I started with this great tutorial (http://tech.pro/blog/1639/using-rjs-to-optimize-your-requirejs-project) and added a infrastructure module which is responsible to load the external libs.
infrastructure.js
define([
'jquery'
], function($) {
'use strict';
});
main.js (it has grown in the last few months a bit :D)
require.config({
urlArgs: 'bust=1386581060770',
paths: {
// jquery: '../../bower_components/jquery/dist/jquery',
jquery: '//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min',
underscore: '../../bower_components/underscore/underscore',
marionette: '../../bower_components/marionette/lib/backbone.marionette',
backbone: '../../bower_components/backbone/backbone',
moment: '../../bower_components/moment/moment',
'moment.de': '../../bower_components/moment/lang/de',
text: '../../bower_components/text/text',
'backbone.modelbinder': '../../bower_components/backbone.modelbinder/Backbone.ModelBinder',
'backbone.analytics': '../../bower_components/backbone.analytics/backbone.analytics',
'requirejs-i18n': '../../bower_components/requirejs-i18n/i18n',
'jquery.cookie': '../../bower_components/jquery.cookie/jquery.cookie',
'jquery.simplePagination': '../../bower_components/jquery.simplePagination/jquery.simplePagination',
'underscore.string': '../../bower_components/underscore.string/dist/underscore.string.min',
parsleyjs: '../../bower_components/parsleyjs/dist/parsley',
'parsleyjs-de': '../../bower_components/parsleyjs/src/i18n/de',
'parsleyjs-comparison': '../../bower_components/parsleyjs/src/extra/validator/comparison',
requirejs: '../../bower_components/requirejs/require',
'underscore.deepExtend': '../../vendor/others/tools/underscore.mixin.deepExtend',
'underscore.templatehelper': '../../vendor/others/tools/underscore.mixin.templateHelper',
templates: '../templates',
infrastructure: 'infrastructure',
confighandler: 'config/confighandler',
layout: 'views/layout',
general: 'general',
helper: 'helper',
vent: 'vent',
view: 'views',
model: 'models',
module: 'modules',
behaviors: 'behaviors',
collection: 'collections',
controller: 'controllers',
nls: 'nls',
'bootstrap-select': '../../bower_components/bootstrap-select/bootstrap-select',
'eonasdan-bootstrap-datetimepicker': '../../bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
'eonasdan-bootstrap-datetimepicker.de': '../../bower_components/eonasdan-bootstrap-datetimepicker/src/js/locales/bootstrap-datetimepicker.de',
'bootstrap': '../../bower_components/bootstrap/dist/js/bootstrap',
'jquery-cropbox': '../../bower_components/jquery-cropbox/jquery.cropbox',
'jquery-geocomplete': '../../bower_components/jquery-geocomplete/jquery.geocomplete',
'seiyria-bootstrap-slider': '../../bower_components/seiyria-bootstrap-slider/js/bootstrap-slider',
'leaflet': '../../vendor/leaflet/leaflet-custom',
modernizr: '../../bower_components/modernizr/modernizr',
intro: '../../bower_components/intro.js/intro',
lightbox2: '../../bower_components/lightbox2/js/lightbox'
},
shim: {
'underscore.deepExtend': 'underscore',
'underscore.string': 'underscore',
'parsleyjs': 'jquery',
'eonasdan-bootstrap-datetimepicker': 'moment',
'parsleyjs-comparison': 'parsleyjs',
'parsleyjs-de': 'parsleyjs',
'select2-de': 'select2',
'lightbox2': 'jquery',
'jquery.simplePagination': 'jquery',
'bootstrap-select': 'bootstrap',
'bootstrap-slider': 'bootstrap',
'backbone.modelbinder': 'backbone',
underscore: {
deps: ['jquery'],
exports: '_'
},
backbone: {
deps: [
'underscore',
'jquery'
],
exports: 'Backbone'
},
'backbone.analytics': {
deps: [
'underscore',
'backbone'
],
exports: 'Backbone.Analytics'
},
'backbone.deepmodel': {
deps: [
'underscore',
'backbone'
]
},
marionette: {
deps: [
'backbone'
],
exports: 'Backbone.Marionette'
},
leaflet: {
exports: 'L'
},
'jquery-geocomplete': {
deps: [
'jquery',
'general/googlemaps'
]
}
}
});
require(['infrastructure'], function() {
'use strict';
console.log('infrastructure');
require(['app', 'model/session'], function(App, Session) {
console.log('app, model/session');
App.session = Session;
App.session.login(function() {
App.start();
});
});
});
the build.js part included in my grunt configuration
requirejs: {
compile: {
options: {
mainConfigFile: 'app/scripts/main.js',
paths: {
jquery: 'empty:'
},
modules: [{
name: 'main',
exclude: [
'infrastructure'
]
}, {
name: 'infrastructure'
}],
findNestedDependencies: true,
preserveLicenseComments: false,
stubModules: ['text'],
inlineText: true,
optimize: 'none',
dir: '<%= build.dest %>/app/scripts/',
wrapShim: true
}
}
}
On the first step I only wanted to include jquery from a CDN. After the build process I've got two files a main.js and the infrastrucute.js. But if I try to run the application that error message is thrown in the console:
Uncaught Error: Bootstrap's JavaScript requires jQuery
I thought this problem wont occur, because the app requires the manufacture-module before all other parts of the application and the dependent libraries were loaded in the main.js. But it seems that all dependencies within main.js are still being loaded before the manufacture-module.
At the moment I'm a bit confused and don't know how to go on or even where to start.
Does anybody has already optimized apps from that size using r.js with libs from CDN. In addition what do you think about the concatenating/minification process + loading libs from a CDN at all? Does it boost the loading performance really?
thx in advance
Add a dependancy on JQuery for Bootstrap. When JQuery was loaded from your server, it is loaded fast enough to be available when Bootstrap starts. Now that JQuery comes from a CDN, it takes more time to be loaded, and is not available when Bootstrap starts.

Can't use requirejs

I'm newby in require.js.
I have next trouble.
I linked require.js :
<script data-main="/Scripts/page/main" src="/Scripts/framework/require.js"></script>
code main.js
require.config(
{
shim: {
backbone: {
exports: 'backbone'
}
},paths: {
jquery: "/Scripts/framework/jquery/jquery-1.6.4",
underscore: "/Scripts/framework/underscore/underscore",
backbone: "/Scripts/framework/backbone/backbone"
}
});
require(["jquery"], function (jquery) {
// why jquery is undefined?
})
I tried to use it like in manual, but unfortunately it's doesnt work.
Why in require function jquery variable is undefined?
Thanks for any help.
The problem is that your baseUrl, where requireJs will load the script from, is the one you specify in the data-main attribute. From the docs:
If no baseUrl is explicitly set in the configuration, the default
value will be the location of the HTML page that loads require.js. If
a data-main attribute is used, that path will become the baseUrl.
According to this, your paths need to look like this:
require.config({
shim: {
backbone: {
exports: 'backbone'
}
},
paths: {
jquery: "../Scripts/framework/jquery/jquery-1.6.4",
underscore: "../Scripts/framework/underscore/underscore",
backbone: "../Scripts/framework/backbone/backbone"
}
You could also set the baseUrl to the root of your project like this:
require.config({
baseUrl: "./",
shim: {
backbone: {
exports: 'backbone'
}
},
paths: {
jquery: "Scripts/framework/jquery/jquery-1.6.4",
underscore: "Scripts/framework/underscore/underscore",
backbone: "Scripts/framework/backbone/backbone"
}
I just ran through the same problem.
Im also new in it but I found a good solution explained here Loading Backbone and Underscore using RequireJS
Basically is extend the shim to:
requirejs.config({
baseUrl: 'js/lib',
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'backbone'
}
},
paths: {
app: '../app',
jquery: 'jquery-1.10.2.min',
backbone: 'backbone.min',
underscore: 'underscore.min'
}
});
requirejs(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
console.log('here');
});
Seems underscore _ and backbone depending on both jquery and underscore cause this.
It works for me and makes sense.
Please correct me If it doesnt.

Using require-js and grunt.js - error missing either a "name", "include" or"modules" option

My Gruntfile.js file:
module.exports = function (grunt) {
grunt.initConfig({
pkg : grunt.file.readJSON('package.json'),
requirejs : {
compile: {
options: {
baseUrl: "public_html/js",
mainConfigFile: "public_html/js/config.js",
out: "public_html/app.min.js"
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', ['requirejs']);
};
My config.js file:
'use strict';
require.config({
deps: ['main'],
paths: {
jquery: 'vendor/jquery',
jquery_tokeninput: 'vendor/jquery.tokeninput',
underscore: 'vendor/underscore',
backbone: 'vendor/backbone'
},
shim: {
jquery: [],
jquery_tokeninput: {
deps: ['jquery']
},
backbone: {
deps: ['vendor/underscore', 'vendor/jquery', 'vendor/jquery.tokeninput'],
exports: 'Backbone'
},
underscore: {
exports: '_'
}
}
});
require(['views/app'], function(AppView) {
new AppView;
});
When I run grunt requirejs it errors with:
Running "requirejs:compile" (requirejs) task
[Error: Error: Missing either a "name", "include" or "modules" option at function.build.createConfig (D:\project\node_modules\grunt-contrib-requirejs\node_modules\requirejs\bin\r.js:24829:19)]
First time using gruntjs and requirejs so not sure why I'm getting the error.
Updated the grunt.js file to use name:
module.exports = function (grunt) {
grunt.initConfig({
pkg : grunt.file.readJSON('package.json'),
requirejs : {
compile: {
options: {
name: "views/app",
baseUrl: "public_html/js",
mainConfigFile: "public_html/js/config.js",
out: "public_html/app.min.js"
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', ['requirejs']);
};
and removed the following from the config.js:
require(['views/app'], function(AppView) {
new AppView;
});

Require.js + SignalR

I have been working with Require.JS and SignalR over the past few days and I noticed that when I load my site sometimes the SignalR/Hubs seems to get loaded before jquery despite my require.js configuration appearing to be correct.
Here's my config:
require.config({
paths: {
jQuery: 'libs/jquery/jquery',
Underscore: 'libs/underscore/underscore',
Backbone: 'libs/backbone/backbone',
Marionette: 'libs/backbone/backbone.marionette'
}
});
require([
'app',
'order!libs/jquery/jquery-min',
'order!libs/jQueryUI/jquery-ui-1.8.11.min',
'order!libs/jqGrid/grid.locale-en',
'order!libs/jqGrid/jquery.jqGrid.min',
'order!libs/underscore/underscore-min',
'order!libs/backbone/backbone-min',
'order!Marionette',
'order!libs/jquery.signalR-0.5.1',
'order!noext!signalr/hubs'
], function (app) {
app.initialize();
});
When this fails I get an error on line 16 of the hubs file. It says uncaught TypeError: Cannot read property 'signalR' of undefined.
Upgraded to V2 and modified my config.
var fRequire = require.config({
paths: {
jQuery: 'libs/jquery/jquery',
Underscore: 'libs/underscore/underscore',
Backbone: 'libs/backbone/backbone',
Marionette: 'libs/backbone/backbone.marionette',
sigr: 'libs/jquery.signalR-0.5.1'
},
shims: {
"libs/jquery.signalR-0.5.1": {
deps: ["jQuery"]
},
"libs/jqGrid/jquery.jqGrid.min": {
deps: ["jQuery"]
},
"libs/jquery/jquery-ui-1.8.19.min": {
deps: ["jQuery"]
},
"libs/jqGrid/grid.locale-en": {
deps: ["jQuery"]
},
"noext!signalr/hubs": {
deps: ["sigr"]
}
}
});
fRequire([
'app'
], function (app) {
app.initialize();
});
Now require is looking in the wrong locations for jquery, underscore, etc...despite my telling it specifically where to look. Perhaps this has something to do with me following an old tutorial when I configured require using v1.
http://backbonetutorials.com/organizing-backbone-using-modules/
FINAL UPDATE:
Here is my working config. Hopefully it'll help any newbies like myself get passed this issue.
require.config({
baseUrl: '/js',
paths: {
"jquery": 'libs/jquery/jquery-min',
"underscore": 'libs/underscore/underscore-min',
"backbone": 'libs/backbone/backbone-min',
"marionette": 'libs/backbone/backbone.marionette',
"sigr": 'libs/jquery.signalR-0.5.1'
},
shims: {
"backbone": {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
"underscore": {
deps: ["jquery"]
},
"marionette": {
deps: ["backbone", "jquery"]
},
"sigr": {
deps: ["jquery"]
},
"libs/jqGrid/jquery.jqGrid.min": {
deps: ["jquery"]
},
"libs/jquery/jquery-ui-1.8.19.min": {
deps: ["jquery"]
},
"libs/jqGrid/grid.locale-en": {
deps: ["jquery"]
},
"noext!signalr/hubs": {
deps: ["sigr"]
}
}
});
// for future ref, I loaded jquery here because app.js references sigr which requires it.
// without enabling it before the module is loaded sigr would complain jquery was not enabled.
require([
'libs/domReady',
'app',
'jquery'
], function (domReady, app, $) {
domReady(function () {
app.initialize();
});
});
It was mandatory that I load jquery in the function(domready, app, $). Failing to do so will result in signalr reporting that it cannot be found.
If you're using requirejs 2.x you can use the "shims" config attribute. There you can specify the dependencies between files that are not AMD compliant, like jquery, jqueryui, etc..
Using your configuration as example:
require.config({
paths: {
jQuery: 'libs/jquery/jquery',
Underscore: 'libs/underscore/underscore',
Backbone: 'libs/backbone/backbone',
Marionette: 'libs/backbone/backbone.marionette'
},
// specify depedencies
shim: {
"libs/jquery.signalR-0.5.1" : {
deps: ["jQuery"]
},
"libs/jqGrid/jquery.jqGrid.min" : {
deps: ["jQuery"]
}
}
});
Also, configure the dependencies in "shims" eliminates the use of the "order!" plugin.
Tip: Use "paths" to set a friendly name for apis that your system use, so when a new version of that api is released you can just change in "paths" and you're done.
Just to follow up on the answer provided and why you are still having to pre-include jQuery... the config setting for require is "shim", not "shims". Require won't recognize and preload the dependencies specified without the correct spelling of the config setting. I got hammered by this recently and posted about it: http://mikeycooper.blogspot.com/2013/01/requirejs-20-dependencies-seemingly.html

Resources