Require AMD modules in Node.js as native modules.
JavaScript
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
LICENSE
README.md
amdrequire.js
changelog.md
package.json

README.md

amdrequire

AMDrequire is NPM package that makes Node understand modules defined in AMD format. When using AMDrequire it is possible to define a module like this.

world.js

define([], function() {
	return "world";
});

And use it like an usual AMD module.

require(['world.js'], function(world){
	console.log('Hello ' + world); //Outputs a brand new "Hello world"
});

AMDrequire also respect node module definitions, so it is still possible to load node modules as usual

var moduleExports = require('module');

Making Node understand both formats let the developer reuse browse code in the server without modifications, basically require.js modules, and write modules directly to be used in both places.

License

Licensed under BSD-2. See license

How to install

Using npm you only need to type in the console

npm install amdrequire

How to use

AMDrequire overrides Node's require function to check whether a request of an AMD or Node module is happening, so it is recommended to require it in the first line of your application's main file.

require = require('amdrequire');

Once AMDrequire is initialized, the require function will understand AMD requires and defines in every module, no more set up needed.

How to configure

The configuration is really similar to the require.js one, the first require object has a config method that accepts a paths attribute to define the named requires:

require = require('amdrequire');
require.config({
	paths: {
		'world': 'somedir/world'
	}
	basePath: __dirname + '/public/assets/js',
	publicPath: __dirname + '/public'
});

Using the example above, when calling require(['world']) AMDrequire will look up the module in the file public/assets/js/somedir/world.js relative to the current dir. The config method is only available when AMDrequire is required for the first time, and not in other modules.

Let's have a look at the options of the config method:

paths

Defines some named requires, so to use those modules it is not needed to write their full path, just the name defined here. The paths are relative to the basePath attribute.

Note: This named requires only affects to AMD requires so you won't be able to call require('world') outside a ```define`` to get the world module.

basePath

The basePath option set the root directory for AMD requires. All the relative paths used in AMD's require and define calls, that don't start with ./ or ../ will be relative to this directory. It is equivalent to require.js baseUrl option, so it should point to the local path of that URL.

publicPath

Defines the path of the root URL directory. In the browser it is possible to require modules using root routes, they start with a slash / like /route/from/the/root. publicPath tells what is the equivalent to that / route to AMDrequire, so it can handle this kind of requires.

Some tips

Reusing require.js configuration

It is possible to reuse the configuration object used for require directly with AMDrequire, so you can define your module paths in one site. The easiest way is creating a module with that data:

config.js

define({
	path:{
		'hello': 'path/to/hello',
		'world': 'way/to/get/the/world'
	},
	baseUrl: '/js'
	// Some more require.js configuration
});

Yes, with require.js it is possible to define modules as objects using the object as the first parameter, and yes, AMDrequire knows about it, so you can use that module to config AMDrequire this way:

require = require('amdrequire');
require(['config.js'], function(config){
	// Set basepaths first
	config.basePath = __dirname + '/public/js';
	config.publicPath = __dirname + '/public';
	require.config(config);
});

Using AMD modules as Node modules

When an AMD module is required once, its exported value is stored in the cache like any other Node module, so you can require it using Node notation and the module path:

require(['world'], function(world){
	// ...do any stuff
});

var world = require('path/to/world');
console.log('Hello ' + world); // Will output "Hello world"

However, you can't require an AMD module using its name, unless you are inside a define function.

require(['world'], function(world){
	// ...do any stuff
});

require(__dirname + '/path/to/world'); // world
require('world'); // fail!!
define([], function(){
	// This will return the result if the 'world' module
	// has been required before.
	var world = require('world');
});

AMDrequire modules are not asynchronous

In case you don't know, AMD stands for Asynchronous Module Definition, but since AMDrequire is using Node's require function to get their modules, their fetching is actually synchronous. It is possible to make code like this:

var mundo;
require(['world'], function(world){
	mundo = world;
});
console.log('Hello ' + mundo);
// Outputs "Hello world" because the code inside the require
// callback is always executed before this line.

What's next?

AMD has just born and I am sure there are lots of ways of improve it. Feel free to fork it and make pull requests. These are some ideas.

Shims

require.js allows third party libraries to be used as modules exporting some variable as the return of the module. They are called shims and AMDrequire doesn't support them yet.

require protocol paths

require.js allows to load files using protocols, like 'http' or 'https'. AMDrequire doesn't support this feature and using protocols will lead to errors.

I am not sure if load external files is a good idea in Node apps, but I am sure that if protocol and domain matches our protocol and domain AMDrequire should work as if the require was local and it is not working like this yet.

I personally would recommend always using relative paths instead of complete URLs.

More testing

There is a small node app to test AMDrequire called amdrequire-test. It tests the different ways that require.js load the files, but I am sure that those tests can be improved. Also, testing possible Node and AMD require conflicts would be great.

Plugins

No plugins are yet supported. I haven't investigated about how to do it, but it would be great to give universal require.js plugin support. If complete plugin support is not possible, at least would be great to have text plugin support.

Named defines

AMDrequire doesn't support named defines as they appeare in the require.js docs. It shouldn't be difficult to support them.

References

This piece of code has been developed with one eye on the Node's module source code and the other on the require.js documentation.

If you want to know more about javascript modules implementation Addy Osmani's writing modular js article is a must.