Search code examples
javascriptmodulerequirejsamdcurl.js

how do I use curl.js to load an object?


Curl 0.7.3

I got some AMD/CommonJS adapter code from here: supporting both CommonJS and AMD

(function (name, definition) {
      if (typeof module != 'undefined') {
        module.exports = definition();
      }
      else if (typeof define == 'function' && typeof define.amd == 'object') {
        define(name, [], definition);
      }
      else {
        this[name] = definition();
      }
    }('modXyz', {
          sayHi:function (name) {
            console.log('Hi ' + name + '!');
          }
        }
    ));

I'd like to use that code with Curl to make all my code AMD/CommonJS compatible. What I was expecting to be able to do was this:

greeter = curl(['modXyz']); 
greeter.sayHi("Gracie"); 

But the object that curl returns isn't the object I'm expecting. The closest I can get is this:

curl(['modXyz'], function(mod) { window.greeter = mod; }); 
greeter.sayHi("Gracie");

Which seems to defeat the purpose of AMD. Is curl capable of doing something like this? Do I have to use require.js to get it to happen?


Solution

  • Because the browser is remote from its resources, it has to either block the main thread while it fetches those resources or it has to fetch them asynchronously. Since we should never block the main thread (effectively making the browser unresponsive), we have to fetch resources async. (It's the same with any AMD loader, RequireJS, dojo, etc.)

    Therefore, things like the following just can't work:

    var foo = require('lib/foo');
    

    Well, it can't work in the usual global-ish space you may be used to in browsers. It can, however, work in a controlled environment such as inside an AMD module.

    Step 1: write your code inside of modules.

    Step 2: write a bootstrap module to launch your app.

    <script src="lib/curl/src/curl.js"><script>
    <script src="myapp/run.js"><script>
    

    Inside run.js:

    // curl 0.7.x requires a named module here ('myapp/run')
    define('myapp/run', ['curl'], function (curl) {
        curl.config(
            baseUrl: '',
            packages: [ /* configure your 3rd-party packages */ ],
            paths: { /* configure any non-package 3rd-party libs here */ },
            preloads: [ /* put modules that *must* be loaded first here (e.g. shims) */ ],
            main: 'myapp/main'
        });
    });
    

    "myapp/main" could then look something like this:

    define(function (require) {
        var view1 = require('myapp/view1/controller');
        view1.render();
        view1.placeAt('body');
    });
    

    Inside the main module (or any AMD module), the require acts more like I think you're expecting. Note that this is a special AMD signature. You can't specify dependencies in the define and expect the require to behave like this. You have to specify your dependencies in only one way. This will not work:

    define(['myapp/view1'], function (view1) {
        var foo = require('foo');
    });
    

    Hope this helps.

    -- John