3

I recently started a Javascript project and I am now moving it to require.js. Everything worked fine so far except for the spin.js library. I get the following error message when I try to access anything spin.js related:

Uncaught ReferenceError: Spinner is not defined

My requirejs.config looks like this:

requirejs.config({

    baseUrl: 'js',

        paths: {
            'jquery': 'lib/jquery',
            'spin': 'lib/spin',
    },

    shim: {
        'jquery' : {
            deps: [],
        },

        'spin' : {
            deps: [],
            exports: 'Spinner'
        },
    }
});  

A sample module looks like this:

require(['spin'], 
    function(Spinner)
    {   
        new Spinner();
    }
);

I'm using the shim config because I have some other modules with dependencies. Everything else seems to be loading fine though. What am I missing here?

Edit:

As Alex pointed out my library inclusion was wrong. For everyone having troubles with understanding backbone.js and require.js I suggest this book, especially the chapter about modular development.

2 Answers2

2

The spin library should not be shimmed in your config. From the spin.js source code:

  if (typeof define == 'function' && define.amd)
    define(function() { return Spinner })
  else
    window.Spinner = Spinner

It is already defined as a module here at the end, and window.Spinner is not created as a window object (which is why it shouldn't be shimmed)

  • That means it should be sufficient to only specifiy spin.js in the paths attribute and keep the reference to it in the module dependencies, right (i.e. drop the 'spin' part in the shim attribute)? Because I tried that as well and it does not work either. –  Feb 25 '13 at 12:00
  • 3
    It would need to be defined in your app. Try: `define(['spin'], function(Spinner){ var mySpinner = new Spinner().spin(); } );` – Alex Ehrnschwender Feb 25 '13 at 12:10
  • 1
    @Jazzturtle to insert mySpinner into the page you would need to add something like: `var target = document.getElementById('foo'); target.appendChild(mySpinner.el);` – Alex Ehrnschwender Feb 25 '13 at 12:42
  • Thanks, Alex. That was very helpful. I have another minor question though (in case this should be a seperate thread, please let me know). I'm trying to use the jquery.spin plugin as well and it still does not work. Should it not be sufficient to add 'spin' and 'jquery.spin' to the dependencies of a module to enable support for said plugin? As you can see, I'm still struggling with the comprehension of the scope of imported libraries. Can you suggest any further resources regarding this topic? Unfortunately, the requirejs documentation left some blanks in my head. –  Feb 25 '13 at 16:25
  • 1
    Sure. The jquery spin plugin I think you're referring to isn't AMD compliant (it doesn't define and return itself) so you would need to shim it with both deps on jquery & spin.js and an export name for the the lib you have just shimmed. If you want to use this throughout your codebase, use define() to create a module of these libs and returns an object with both - then use that combined module thru require() elsewhere. The asynchronous dependencies are a bit confusing and it takes some practice to get the hang of it. Other than trial and error you can check the docs, source, and this site. – Alex Ehrnschwender Feb 25 '13 at 18:24
1

I had a case of something similar. I didn't add to shim but neglected to add Spinner to the function after Backbone which caused it to be undefined.

define([
  'jquery',
  'underscore',
  'backbone',
  'spin'
],

function($, _, Backbone, Spinner) {
  var SpinnerView = Backbone.View.extend({

    initialize: function() {

      this.loadingAnimation();
    },
Mr Brimm
  • 133
  • 2
  • 12