Converting CommonJS to AMD

3.2k views Asked by At

I have a simple CommonJS module published on NPM and Bower that basically just looks like this:

  function Foo(){}

    module.exports = new Foo();

now the easiest way to convert to AMD format would be just to publish a second version that was AMD compatible like so:

define(function (require, exports, module) {

    function Foo(){}

    module.exports = new Foo();

});

but I thought there was a way you can shim the CommonJS module using requirejs.config like so:

requirejs.config({

   paths:{
    'foo':'assets/vendor/foo'
   },
   shim:{

     'foo' :{
       exports: 'Foo'
      }
   }
});

but this doesn't seem to work. I figure that the shim tool does the wrapping that I did above for you, but I am not entirely sure.

1

There are 1 answers

0
Louis On BEST ANSWER

The Problem

shim cannot do as much as you want it to do. When RequireJS evaluates the symbol you give in exports, it evaluates it in the global space. So using exports works fine if you can access the variable you want to export from the global space. If library foo exports Foo into the global space, that works fine.

What you are trying to do is have a module that exports its API through module work with a shim. This cannot work because RequireJS cannot guess that the module being loaded requires that a global module object be already available to the module being loaded. In the simplest case, loading such module will result in a ReferenceError because module does not exist. There would be ways to fake the module.exports thing that would work in the most trivial cases but it would not work as a general solution.

A Solution

You can use r.js to convert files that are written in the CommonJS format to what RequireJS needs. It is documented here. The documentation gives the following synopsis:

node r.js -convert path/to/commonjs/modules/ path/to/output

You should also read this part of the README for some caveats.