I've got a module that I'd like to include in a Require.js chain. (More specifically: )
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)
I've got a module that I'd like to include in a Require.js chain. (More specifically: https://github./ponent/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)
Share Improve this question edited Feb 28, 2013 at 17:19 Charles 51.4k13 gold badges106 silver badges144 bronze badges asked Feb 28, 2013 at 11:05 Geert-JanGeert-Jan 18.9k19 gold badges81 silver badges145 bronze badges 2- Node.js implements the CommonJS modules specification, not AMD supported by RequireJS. CommonJS modules can be adapted to AMD either manually of automatically (by using r.js), more information on the requirejs docs page. On-the-fly conversion doesn't seem to be mentioned at all, though. – kryger Commented Mar 3, 2013 at 18:03
- @Geert-Jan This looks like something from the ponent framework. See github./ponent/todo for how to use it – SheetJS Commented Jun 7, 2013 at 17:45
1 Answer
Reset to default 5Components are CommonJS modules
The Components framework is a collection of, well, ponents 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.
Manually wrapping a CommonJS module
define(function(require, exports, module) {
//Put traditional CommonJS module content here
});
From: CommonJS Notes
Automatically wrapping with r.js
r.js -convert path/to/monjs/modules path/to/converted/modules
Given that you have already installed r.js
with npm -g i requirejs
.
Solving the specific problem
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.
Truly AMD
The holy grail would be an EventEmitter type library that's small and AMD patible. 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 */ });