How to use hammer.js plugins with require.js - requirejs

I am trying to use hammer.js plugins with require.js but I have no luck.
Here is my code:
requirejs.config({
paths: {
"jquery": ('__proto__' in {}) ? "lib/zepto" : "lib/jquery",
"hammer-jquery": "lib/jquery.hammer",
"hammer-showtouches": "lib/hammer.showtouches",
"hammer-fakemultitouch": "lib/hammer.fakemultitouch"
},
shim: {
"jquery": {
exports: "$"
},
"hammer-showtouches": {
deps: [ "hammer-jquery" ],
exports: "Hammer.plugins.showTouches"
},
"hammer-fakemultitouch": {
deps: [ "hammer-jquery" ],
exports: "Hammer.plugins.fakeMultitouch"
}
},
waitSeconds: 30
});
requirejs(["jquery","hammer-jquery","hammer-showtouches","hammer-fakemultitouch"], function ($,Hammer) {
$(function(){
if(!Hammer.HAS_TOUCHEVENTS && !Hammer.HAS_POINTEREVENTS) {
Hammer.plugins.showTouches();
Hammer.plugins.fakeMultitouch();
}
});
});
And here is the error:
Uncaught TypeError: Cannot read property 'plugins' of undefined hammer.showtouches.js:7
Uncaught TypeError: Cannot read property 'plugins' of undefined require.js:8
Uncaught TypeError: Cannot read property 'plugins' of undefined hammer.fakemultitouch.js:7
Uncaught TypeError: Cannot read property 'plugins' of undefined require.js:8
I have tried to include Hammer in shim config with no luck (It's not necessary beacause last version of jquery.hammer is AMD compatible).

Your issue appears to be that you didn't include the hammerjs library which is required by the hammerjs jquery plugin.
To fix this problem, you'll need to add to your requirejs path something like 'hammer':'lib/hammerjs/dist/hammer.min',
Additionally, here's some related information on how I used hammerjs with requirejs.
In my case, I wanted it to work with backbone and requirejs. I installed the libraries with bower.
bower install --save hammerjs
bower install --save backbone.hammer
Then, I proceeded to add the RequireJS configuration:
I noticed that jquery.hammer.js is AMD and automatically requires jquery. It also silently depends on Hammer. It modifies jquery to support Hammer. No shim is required.
I noticed that hammerjs is AMD and automatically exports Hammer. No shim is required.
I noticed that backbone.hammer is AMD and automatically requires underscore, backbone, and hammer. It modifies Backbone to support Hammer. No shim is required.
Therefore, my configuration uses paths only (since no shim support is required):
require.config({
'baseUrl':'',
'paths':{
'underscore':'js/lib/underscore-amd/underscore-min',
'backbone':'js/lib/backbone-amd/backbone-min',
'jquery':'js/lib/jquery/jquery.min',
'hammer':'js/lib/hammerjs/dist/hammer.min',
'jquery-hammer':'js/lib/hammerjs/dist/jquery.hammer.min',
'backbone-hammer':'js/lib/backbone.hammer/backbone.hammer'
},
shim:{
'underscore': { exports: '_' },
'backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone' }
}
});

Wrap HammerJS then bind to the global window:
// #path utils/hammer
define([
'hammer'
], function (Hammer) {
window.Hammer = Hammer;
});
Then make whatever plugins or modules which have dependencies on HammerJS depend on utils/hammer.

Related

How to add AMD/legacy dependency (leaflet) with sub dependencies in requirejs

I installed a AMD module called leaflet and successfully using it as "L".
Next I need a plugin called leaflet.draw but I get confused about the dependencies. Consider the following code:
requirejs.config({
baseUrl: 'bower_components',
paths: {
leaflet: 'leaflet/dist/leaflet-src',
leafletdraw: 'leaflet-draw/dist/leaflet.draw-src'
...
requirejs(["leaflet", "leafletdraw"], function(L, leafletdraw) {
var map = new L.Map('map');
...
This gives a referenceError: L is not defined at Leaflet.draw.js:4. So I guess it needs the leaflet (L) as a dependency, right? I then tried to add it in the shim config:
shim: {
leafletdraw: {
deps: 'leaflet'
}
}
This results in a "Invalid require call". So my question is: How do I properly require a plugin with subdependencies?
The modules are installed with "bower install leaflet" and "bower
install leaflet-draw" respectivily. But im not sure if leaflet-draw
is AMD enabled. Why isnt that stated in repos docs? Can I assume it
is enabled by default?
This is what I try to achive:
http://codepen.io/osmbuildings/pen/LVJzWw, but with requirejs.
Solution: shim leaflet itself, and let it export 'L'. Then putting the deps in plugins will work. My full config:
requirejs.config({
baseUrl: 'bower_components',
paths: {
jquery: 'jquery/dist/jquery.min',
leaflet: 'http://cdn.leafletjs.com/leaflet-0.7.3/leaflet',
'leaflet-draw': 'http://cdn.osmbuildings.org/Leaflet.draw/0.2.0/leaflet.draw',
OSMBuildings: ['http://cdn.osmbuildings.org/OSMBuildings-Leaflet']
},
shim: {
leaflet: {
exports: 'L'
},
'leaflet-draw': {
deps: ['leaflet']
},
OSMBuildings: {
deps: ['leaflet'],
exports: 'OSMBuildings'
}
}
});
requirejs(["jquery", "leaflet", "leaflet-draw", "OSMBuildings"], function($, L, dummy, OSMBuildings) {
var map = new L.Map('map');

Bootstrap library with requirejs

I am trying to use bootstrap with require js. So far jquery, underscore and boostrap are loading fine, but I am having issues with one library not loading: bootstrap-tagsinput. How can I debug requirejs and see whether this library is loading or not?
Here is my common.js
requirejs.config({
shim: {
'jquery': {
exports: '$'
},
'underscore': {
exports: '_'
},
'bootstrap': {
deps: [ "jquery" ]
},
'bootstrap-tagsinput': {
deps: [ "bootstrap" ]
}
},
baseUrl: "/",
paths: {
'jquery': [
'//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min',
'jquery/jquery.min'
],
'underscore': [
'//underscorejs.org/underscore-min',
'underscore/underscore-min'
],
'bootstrap': [
'//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min',
'bootstrap/dist/js/bootstrap.min'
],
'bootstrap-tagsinput': 'bootstrap-tagsinput/dist/bootstrap-tagsinput.min'
}
});
Require.js is invented to handle dependencies between modules, so it is quite clear that you specify those dependencies in the modules where you use it like you said in your own answer already. The function given as the second parameter to define() gets handles to those modules in the order they are given.
As $ is normally used for jQuery library, it is not a good idea to use $ for something else, because this would create a lot of confusion. But normally you need jQuery in a module as well, so your define() call will most probably look like
define['jquery', 'bootstrap-tagsinput'], function($) {
...
});
In this case $ is bound to jQuery, not to bootstrap-tagsinput. It is instead called via the jQuery mechanisms, so you don't need a second parameter in the function.
I figured out that 'bootstrap-tagsinput' needs to be defined where it's being used. For example, in a page that makes use of this library:
define(['bootstrap-tagsinput'], function() {
// js for the page here
});
And in order to auto-load modules that should always be available (eg. bootstrap or jquery) we can do the same.
define(['bootstrap'], function() {
// main.js contents
});

RequireJS multipleversion dependencies

I have a couple of different apps in my application. Some newer with Backbone only and older with Marionette, since Marionette uses Backbone both uses Underscore.
Now I want to update Underscore, 1.6.0 -> 1.8.3.
So I make a legacy underscore in my require.config
paths: {
'underscore': 'vendor/underscore/underscore',
'underscore-1.6.0': 'vendor/underscore-1.6.0/underscore',
'backbone': 'vendor/backbone/backbone',
'backbone-1.1.2': 'vendor/backbone-1.1.2/backbone',
'marionette': 'vendor/marionette/lib/core/amd/backbone.marionette',
'backbone.wreqr': 'vendor/backbone.wreqr/lib/backbone.wreqr',
'backbone.babysitter': 'vendor/backbone.babysitter/lib/backbone.babysitter',
},
shim: {
'underscore-1.6.0': {
exports: 'underscore'
},
'backbone-1.1.2': {
deps: ['underscore-1.6.0'],
exports: 'backbone'
},
'backbone.babysitter': {
deps: ['backbone-1.1.2', 'underscore-1.6.0']
},
'backbone.wreqr': {
deps: ['backbone-1.1.2', 'underscore-1.6.0']
},
'marionette': {
deps: ['backbone-1.1.2']
}
},
Marionette depends on both Wreqr and Babysitter, which in turn depending on underscore 1.6.0 (and Backbone 1.1.2). My solution is to add deps for both of them.
My problem is when im trying to require('marionette'); as both wreqr and babysitter are asking for 'underscore' and 'backbone' they are getting the none-legacy not 'underscore-1.6.0' and 'backbone-1.1.2'.
Can I some how decide which version of underscore and backbone "backbone" and "underscore" Wreqr and Babysitter should use?
Is there any other good way to this?
Thank!
Johan
All the packages you mention are proper AMD modules. For each package that does not have a version number, I checked the sources of the latest version. For versioned names, I checked the specific version in the name. In all cases, they check for the existence of define.amd and call define. Therefore, they are proper AMD modules. Consequently, you cannot use shim with them. The shim configuration is only for modules that are not really AMD modules (do not call define).
Now, the problem is that packages that need Backbone will require backbone and those that need Underscore will require underscore. They do not distinguish by version. You can force them to use specific versions by using the map configuration:
map: {
'backbone-1.1.2': {
underscore: 'underscore-1.6.0'
},
'backbone.babysitter': {
backbone: 'backbone-1.1.2',
underscore: 'underscore-1.6.0'
},
'backbone.wreqr': {
backbone: 'backbone-1.1.2',
underscore: 'underscore-1.6.0'
},
marionette: {
backbone: 'backbone-1.1.2'
}
}
Everywhere in your application if backbone or underscore are required then the modules backbone or underscore are loaded. The map establishes exceptions to this rule. When backbone.babysitter requires backbone then backbone-1.1.2 is loaded instead. When it requires underscore then underscore-1.6.0 is loaded instead. Similarly for the other modules in the map.

require js beginner - dependency injection

I'm a beginner with require js and I have a doubt here.
My files are structured like below:
root
|____assets
|____bootstrap-3.0.1
|________dist
|____________js
|____________bootstrap.min.js
|________js
|________angulajs.min.js
|________app.js
|________jquery.min.js
|________underscorejs-min.js
|____________app
|________________main.js
My app.js file is like below:
requirejs.config({
"baseUrl": "assets/js",
"paths": {
": "app",
"jquery": "jquery.min",
"jquery-migrate": "jquery-migrate.min",
"twitter-bootstrap": "../bootstrap-3.1.0/dist/js/bootstrap.min",
"underscore": "underscore-min"
},
"shim": {
"twitter-bootstrap": {
deps: [ "jquery" ]
}
}
});
requirejs(["app/main"]);
My main.js is like below:
define([ "jquery", "twitter-bootstrap" ], function($) {
$(function() {
$("#teste").tooltip();
});
});
My question is about the main file and the dependency jquery in the case of bootstrap. If I had declare that the Bootstrap depends on jQuery I still have to include "jquery" in define function?
I tried to remove "jquery" declaration but the dependency was not injected and I received a undefined error.
Thanks for any help!
Doing it like this is really the way to go:
define([ "jquery", "twitter-bootstrap" ], function($) {
$(function() {
$("#teste").tooltip();
});
});
In the code above, it is clear that $ should be bound to the jquery module. If you do this:
define(["twitter-bootstrap" ], function($) {
$(function() {
$("#teste").tooltip();
});
});
You are binding $ to the twitter-bootstrap module. This won't work without further configuration because twitter-bootstrap exports nothing. (It installs itself as a jQuery plugin.) You could work around it by setting your shim like this:
"shim": {
"twitter-bootstrap": {
deps: [ "jquery" ],
exports: '$.fn.tooltip',
init: function ($) { return $; }
}
}
However, I don't recommend this since someone who comes across the code without knowing the context (that is, not knowing the relationship between the jquery and twitter-bootstrap modules) won't readily know what is going on.
In the shim above the exports field is not absolutely necessary but it help RequireJS know when Bootstrap has been loaded. It should be a symbol that does not exist prior to Bootstrap being loaded but exists after it is loaded.

RequireJS Optimizer throws ReferenceError: text is not defined

I have been using r.js to attempt to minify a fairly large project and I'm having trouble with the text plugin. I am using node.js and a build file that goes as follows:
Build File
({
name: '../main',
baseUrl: '../../js/app',
appDir: "./app",
dir: 'build',
paths: {
jquery: '../lib/jquery/jquery-1.10.2.min',
underscore: '../lib/underscore/underscore-min',
backbone: '../lib/backbone/backbone-min',
text: '../lib/require/text',
picker: '../lib/pickadate/picker',
pickerDate: '../lib/pickadate/picker.date',
pickerLegacy: '../lib/pickadate/legacy'
},
mainConfigFile : '../js/main.js'
})
Main Config File
requirejs.config({
baseUrl: 'js/app',
paths: {
jquery: '../lib/jquery/jquery-1.10.2.min',
underscore: '../lib/underscore/underscore-min',
backbone: '../lib/backbone/backbone-min',
text: '../lib/require/text',
picker: '../lib/pickadate/picker',
pickerDate: '../lib/pickadate/picker.date',
pickerLegacy: '../lib/pickadate/legacy'
},
shim: {
picker: ['jquery', 'pickerLegacy'],
pickerDate: {
deps: ['jquery', 'picker'],
exports: 'DatePicker'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
underscore: {
exports: '_'
},
text : {
exports : 'text'
}
}
});
The references above are all verified correct. Whenever I try to compile this, I get the following output in the console:
node r.js -o app.build.js
Tracing dependencies for: ../main
ReferenceError: text is not defined
In module tree:
../main
app
router
views/pages/home
views/panel/allStoresPanel
text
Error: ReferenceError: text is not defined
In module tree:
../main
app
router
views/pages/home
views/panel/allStoresPanel
text
at eval (eval at <anonymous> (C:\code\Web\DixonsDashboard\deploy\_compiler\r.js:23699:64), <anonymous>:1:1)
I have no idea why it finds text to be undefined. The path to it is definitely correct - the site works like a charm in it's current expanded format. I have tried all of the options available to r.js and none of them seem to make any difference.
If I delete the file, I get a "No such file or directory" error, so it looks like it's finding the file OK.
Can anybody point out what I'm missing here?
You only configure shim for plugins that are not AMD compatible. The "text" plugin is already AMD compatible so running it through the shim mechanism actually breaks it.
I've just tested with a simplified version of your code: including text in the shim section does show "ReferenceError: text is not defined", removing it makes the build work fine.

Resources