Search code examples
javascriptamdcurl.js

how should I write my define to work with curl.js?


I'm reading Addy Osmani's excellent blog post about writing AMD modules. I start with a simple chunk of js that I lifted from his post:

define('modTest', [],
  // module definition function
  function () {
      // return a value that defines the module export
      // (i.e the functionality we want to expose for consumption)

      // create your module here
      var myModule = {
        doStuff:function(){
          console.log('Yay! Stuff');
        }
      }

      return myModule;
  }
);

I took out the dependencies on foo and bar. Just want a simple object that logs to the console.

So I save that in /js/modTest.js and then try to load it:

curl(['/js/modTest.js'])
 .then(function(mt) {
     console.log("Load complete"); 
     console.log("mt:"); 
     console.log(mt); 
     mt.doStuff()
  }, function(ex) {alert(ex.message);})

Result: error: Multiple anonymous defines in URL. OK that didn't work. Tried adding in a namespace: define('myCompany/modTest', [],, same result. Tried adding an empty string in the dependency array, same result.

Also tried curl(['modTest.js'], function(dep){console.log(dep)}); with the same result.

Is the code in Addy's blog post incorrect? Am I doing something wrong? Maybe a bug in curl?

Update 5/24: I ditched curl.js in favor of require.js. Zero odd errors, very little work to change over. I did have to deal with amdefine a bit to get my code running client and server side (one object is in both places, so grunt had to be configured to take care of that). My defines generally look like:

define(->
    class AlphaBravo 
    ... 

And never have any trouble loading.


Solution

  • You asked curl() to fetch a module called "/js/modTest.js". It found the file and loaded it and found a module named "modTest", so it complained. :) (That error message is horribly wrong, though!)

    Here's how you can fix it (pick one):

    1) Remove the ID from your define(). The ID is not recommended. It's typically only used by AMD build tools and when declaring modules inside test harnesses.

    2) Refer to the module by the ID you gave it in the define(). (Again, the ID is not recommended in most cases.)

    curl(['modTest'], doSomething);
    

    3) Map a package (or a path) to the folder with your application's modules. It's not clear to me what that would be from your example since modTest appears to be a stand-alone module. However, if you were to decide to organize your app's files under an "app" package, you packages config might look like this:

    packages: [ { name: 'app', location: 'app' } ]
    

    Then, when you have code that relies on the modTest module, you can get to it via an ID of "app/modTest".

    curl(['app/modTest'], doSomething);
    

    I hope that helps clear things up!

    Fwiw, Addy's example could actually work with the right configuration, but I don't see any configuration in that post (or my eyes missed it). Something like this might work:

    packages: [ { name: 'app', location: '.' } ]
    

    -- John