Intern configuration not processing AMD shim - intern

I am trying to test a Require.js project using Intern. I'm running into errors in my tests where jQuery is not defined when jQuery plugins are being loaded. My loader config looks like this:
loader: {
// Aliased paths
paths: {
'dt': 'dt',
'jq': 'jquery',
'jquery': 'jquery/jquery-1.8.3',
'jquerymx': 'jquery/jquerymx-3.2.custom',
'jquery.ui': 'jquery/jquery-ui-1.9.2.custom.min',
'jquery.ui.widget': 'jquery/jquery.ui.widget',
'jquery.jscrollpane': 'jquery/jquery.jscrollpane.min.edit',
'jquery.colorbox': 'jquery/jquery.colorbox-min',
'jquery.selectbox': 'jquery/jquery.selectbox-0.2.min.edit',
'jquery.base64': 'jquery/jquery.base64',
'jquery.cookie': 'jquery/jquery.cookie',
'jquery.urldecoder': 'jquery/jquery.urldecoder.min',
'jquery.fileupload': 'jquery/jquery.fileupload',
'jquery.history': 'history/scripts/compressed/history.adapter.jquery',
'openajax': 'openajax_2.0.7/OpenAjaxUnmanagedHub',
'zeroclipboard': 'zeroclipboard/ZeroClipboard'
},
// Plugin mappings
map: {
'*': {
'css': 'requirejs/require-css/css',
'text': 'requirejs/text'
}
},
// Shims for non-AMD libraries, mainly jQuery plugins
shim: {
'openajax': {
exports: 'OpenAjax'
},
'zeroclipboard': {
exports: 'ZeroClipboard'
},
'jquerymx': ['jquery'],
'jquery.ui': ['jquery'],
'jquery.ui.widget': ['jquery'],
'jquery.jscrollpane': ['jquery'],
'jquery.colorbox': ['jquery'],
'jquery.selectbox': ['jquery'],
'jquery.base64': ['jquery'],
'jquery.cookie': ['jquery'],
'jquery.urldecoder': ['jquery'],
'jquery.fileupload': ['jquery'],
'jquery.history': [
'jquery',
'history/scripts/compressed/history',
'history/scripts/compressed/history.html4'
]
}
}
I've checked to make sure jQuery and my other dependencies are actually being loaded, and they are, just not in the right order. Does the Dojo AMD loader that Intern use not handle the shim configuration?

The problem is that the AMD loader used by intern doesn't currently implement the shim configuration propertyAMD Specification. I was actually unaware that it was part of the standard until you asked this question.
At the moment, you could run functional tests using a different AMD loader via Intern, but at the moment, it would be difficult to run unit tests on the local machine.

All I had to do was point useLoader config to the require.js, and poof. I had the familiar shim config and path config I use in my app. Bam.

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.

Automatically load postrequisite files

I'm looking to automatically load dependant files, similarly to how deps works however these files need to be loaded AFTER the initially requested.
For example:
require.config({
baseUrl: '/',
paths: {
jquery: '/assets/components/jquery/dist/jquery.min',
highcharts: '/assets/components/highcharts/highcharts.js',
'highcharts.more': '/assets/components/highcharts/highcharts-more.js'
},
shim: {
jquery: { exports: 'jQuery' },
highcharts: { deps: ['jquery'] },
'highcharts.more' : { deps: ['highcharts'] },
}
});
define(function (require) {
var app = require('assets/js/app');
app.start();
});
When requiring highcharts, jQuery will automatically be loaded as a dependant, however Highcharts requires that you load two files.
Does anyone know how I can load postrequisite files, i.e. after loading highcharts to automatically load highcharts.more.
I could simply set highcharts a dependency of highcharts-more and load highcharts-more however hoped there was a cleaner way?
Hope this makes sense?!
Thanks
Gav
Loading highcharts.more and making it a dependency of highcharts is the way to go. You can also hide highcharts.more from your modules by using a map configuration:
map: {
"*": {
highcharts: "highcharts.more"
},
"highcharts.more": {
highcharts: "highcharts"
}
}
The mapping above says "in all modules (*) when highcharts is requested, load highcharts.more instead, but in highcharts.more when highcharts is requested load highcharts".
With this, you can just list highcharts as a dependency in your actual modules.

RequireJS + Optimizer Include modules defined on the main file

I'm using Optimizer for the first time and I am running in some issues or questions.
I'm trying to optimize a main file and it puts, like I've expected, the jQuery, Backbone and Require modules ( and uses then across the whole navigation). But let's say I have a jQuery Plugin that I use on several views. I've tried to add it in the main file using the "include" option on the build.js file. It adds it ( e.g jQuery Slides ) but as I have a view with define("jquery-slides") ( again, an example ) the browser loads the file of the plugin again. Even if it is on the main built file.
Is this suppose to happen? Can I fix this?
Thanks.
Here is some code. Hope it helps =)
build.js
{
baseUrl: "javascripts/",
appDir: "..",
dir: "dist",
name: "main-site",
include: ['libs/requirejs/require', jquery-slides'],
insertRequire: ['main-site'],
paths: {
"main-site": 'main-site',
'jquery': 'libs/jquery/jquery',
'jquery-slides': 'libs/jquery/plugins/slides.min.jquery'
}
}
main-site.js
require.config({
baseUrl: "/javascripts/",
paths: {
'jquery': 'libs/jquery/jquery',
'underscore': 'libs/underscore/underscore',
'bootstrap': 'libs/bootstrap/bootstrap.min',
'datepicker': 'libs/bootstrap/plugins/bootstrap-datepicker',
'backbone': 'libs/backbone/backbone.max',
'backbone-paginator': 'libs/backbone/plugins/backbone.paginator',
'backbone-validation': 'libs/backbone/plugins/backbone.validation',
'text': 'libs/requirejs/text',
'templates': '/templates/site',
'views': 'views/site',
'jquery-cookie': 'libs/jquery/plugins/jquery.cookie',
'jquery-raty': 'libs/jquery/plugins/jquery.raty.min',
'jquery-slides': 'libs/jquery/plugins/slides.min.jquery'
},
shim: {
'backbone-paginator': ['backbone'],
'bootstrap': ['jquery'],
'datepicker': ['bootstrap'],
'jquery-cookies': ['jquery'],
'jquery-raty': ['jquery'],
'jquery-slides': ['jquery'],
'backbone-validation': ['backbone']
}
});
require([
'app-site'
], function(App) {
$(function(){
App.initialize();
});
});
Instead of using include I recommend you to declare the modules you want to build. In this way requirejs will package the module and all its dependencies in the optimized bundle.
{
baseUrl: "javascripts/",
appDir: "..",
dir: "dist",
paths: {
"main-site": 'main-site',
'jquery': 'libs/jquery/jquery',
'jquery-slides': 'libs/jquery/plugins/slides.min.jquery'
},
modules : [
{
name : 'main-site',
}
]
}
Further considerations:
If you have jquery-slides included as a dependency in any of your modules define(['jquery-slides'], function() {... } you don't need to use the include directive since all the dependencies of that module will be included in the optimized file
See the documentation of the modules property in this link
https://github.com/jrburke/r.js/blob/master/build/example.build.js#L330
Use the property mainConfigFile to avoid duplications https://github.com/jrburke/r.js/blob/master/build/example.build.js#L35
Good luck and I hope this helps you

Resources