Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shim a module in Require.js that uses module.exports possible?

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)

like image 584
Geert-Jan Avatar asked Feb 28 '13 11:02

Geert-Jan


People also ask

What is shim in RequireJS?

shim: Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value. Here is an example. It requires RequireJS 2.1. 0+, and assumes backbone.

Can I use require in JS file?

“Require” is built-in with NodeJS With require , you can include them in your JavaScript files and use their functions and variables. However, if you are using require to get local modules, first you need to export them using module. exports . For example, let's assume that you have a file called blogDetails.

What is shim in jQuery?

jQuery uses shim configuration to define the dependencies for jQuery plugins and set a module value by declaring dependencies.

How node js modules are exported?

exports is a special object which is included in every JavaScript file in the Node. js application by default. The module is a variable that represents the current module, and exports is an object that will be exposed as a module. So, whatever you assign to module.


1 Answers

Components are CommonJS modules

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.

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/commonjs/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 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 */ });
like image 158
Aintaer Avatar answered Oct 07 '22 19:10

Aintaer