Domanda

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.

È stato utile?

Soluzione

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

Altri suggerimenti

I've just had a similar problem which turned out to be the include order I was using for my other libraries. I'm loading handlebars.js, crossroads.js, jquery and a few other libraries into my project in the traditional way (script tags in head) and found that when I place the curl.js include first, I get this error, but when I include it last, I do not get this error.

My head tag now looks like this:

<script type="text/javascript" src="/js/lib/jquery.js"></script>
<script type="text/javascript" src="/js/lib/signals.js"></script>
<script type="text/javascript" src="/js/lib/crossroads.js"></script>
<script type="text/javascript" src="/js/lib/handlebars.js"></script>
<script type="text/javascript" src="/js/lib/curl.js"></script>
<script type="text/javascript" src="/js/main.js"></script>

You have a problem with your define call. It is NAMED

See AMD spec for full story on how to write defines, but here is what I would expect to see in your js/modTest.js file:

define(/* this is where the difference is */ 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;
  }
);

Now, the boring explanation:

CurlJS is awesome. In fact, after dealing with both, RequireJS and CurlJS, I would say CurlJS is awesome-er than RequireJS in one category - reliability of script execution ordering. So you are on the right track.

On of the major things that are different about CurlJS is that it uses "find at least one anonymous define per loaded module, else it's error" logic. RequireJS uses a timeout, where it effectively ignores cases where nothing was defined in a given file, but blows up on caught loading / parsing errors.

That difference is what is getting you here. CurlJS expects at least one anonymous (as in NOT-named) define per loaded module. It still handles named defines fine, as expected. The second you move the contents of "js/modTest.js" into inline code, you will have to "name" the define. But, that's another story.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top