Reputation: 18895
I've got a module that I'd like to include in a Require.js chain. (More specifically: https://github.com/component/emitter)
On the browser I get:
uncaught reference error: module is not defined
For module export it defines:
module.exports = Emitter;
I guess this is called the AMD / Node way. PLease correct if wrong.
in any case I'd like require.js to be able to module somehow in the browser. I'd thought the declarative shimming opions of Require.js could help me, but I'm still seein the above error.
How could this be resolved, without patching the module by hand? (as I'd like to keep the automated build process I've set up)
Upvotes: 12
Views: 5653
Reputation: 2141
The Components framework is a collection of, well, components written in the CommonJS module format. The intended value of a module is simply assigned to a 'magic property' called module.export
, intended to be provided by the JS runtime.
This is not the way that web JS runtimes work, as CommonJS modules make assumptions to a particular workflow. Without the ability to synchronously guarantee a file has loaded (or catastrophically fail when they don't), browsers cannot support the same workflow as standalone environments. Thus anything written in the CommonJS format must be wrapped to take that into account.
In order to use CommonJS modules with an AMD style module loader like RequireJS, you can either wrap the modules you need yourself or you can use the r.js build tool.
define(function(require, exports, module) {
//Put traditional CommonJS module content here
});
From: CommonJS Notes
r.js -convert path/to/commonjs/modules path/to/converted/modules
Given that you have already installed r.js
with npm -g i requirejs
.
However, all that is just solving the more general problem of "How do I use CommonJS modules in an asynchronous workflow?" What it seems you're actually trying to achieve is just to be able to get an event system without writing it yourself.
Since you're loading this on the client-side, there are plenty of client-side libraries that already offer this functionality. The most popular library that offers this is probably Backbone.js's Events. The upside of using Backbone events is that Backbone is well supported, well documented. The downside is that Backbone is another dependency (including its own dependency, Underscore) that you will have to load. In addition, Backbone exports to a global variable, so you would need to declare a RequireJS shim config to be able to require()
it.
The holy grail would be an EventEmitter type library that's small and AMD compatible. For that you can try using a micro-library like pubsub.js or nbd.js (Disclosure: I am the author of nbd.js).
If you do use nbd.js, it offers more than just pubsub capabilities. But you can specifically require()
just the pubsub module.
If you're using git for source control, it's easiest to use it as a submodule.
git submodule add [email protected]:behance/nbd.js.git path/to/nbd
Then, require
the pubsub module and do what you want!
require(['nbd/trait/pubsub'], function(pubsub) { /* do whatever */ });
Upvotes: 5