RingoJS can do such a thing:
Ringo implements the CommonJS Modules specification. In short this means:
Every JavaScript file is treated a module living in its own top-level scope.
Any function or property attached to a module's exports object will be exposed.
The require() function returns a module's exports object.
If the given identifier string starts with ./ or ../ Ringo's module loader searches for a file and tries to load it. Therefore require('./foo') advices Ringo to load the file ./foo.js as module.
Otherwise Ringo looks for the module in every folder of the module path.
The module path is a list of standard locations in which Ringo will look for modules.
The module path can be set in the following ways:
Setting the RINGO_MODULE_PATH environment variable.
Setting the ringo.modulepath Java system property.
Using the -m or --modules option to the ringo command-line tool.
Using the module-path servlet init parameter with JsgiServlet.
Adding or removing elements to the require.paths Array-like property from within Ringo.
Packages provide a means of bundling several modules and other resources into one unit. Packages are directories that contain a package.json package descriptor file. The main property in the package.json descriptor is recognized by Ringo's module loader as the main entry point for a module:
{
"main": "lib/main.js"
}
If a module id resolves directly to a package directory and package.json defines a main property, Ringo will try to load the specified resource. The value of the main property must be a path relative to the package root.
If a module id resolves to a directory that does not contain a package.json file, or package.json does not define a main property, Ringo will try to load file index.js in that directory.
If part of a module id resolves to a package directory, Ringo will try to resolve the remaining part of the id against the lib directory of that package. The location of the lib directory can be overridden using the directories.lib property in package.json.
{
"directories": {
"lib": "new-lib"
}
}
The CommonJS modules specification was kept deliberately small. Ringo provides some extra niceties for exporting and importing stuff. The downside to using these is that your code is tied to Ringo, but it's relatively easy to convert the code to "pure" CommonJS, and there's also a command line tool for that purpose.
One Ringo extension is the include function. This is similar to require, but instead of returning the other module's exports object as a whole it directly copies each of its properties to the calling module's scope, making them usable like they were locally defined.
include is great for shell work and quick scripts where typing economy is paramount, and that's what it's meant for. It's usually not a great idea to use it for large, long lived programs as it conceals the origin of top-level functions used in the program.
For this purpose, it's more advisable to use require in combination with JavaScript 1.8 destructuring assignment to explicitly include selected properties from another module in the local scope:
var {foo, bar} = require("some/module");
The above statements imports the "foo" and "bar" properties of the API exported by "some/module" directly in the calling scope.
Writing command line scripts with Ringo is straightforward. Every arbitrary JavaScript file can be passed as [script-file] argument to the ringo command:
ringo [script-file] [script-arg1] [script-arg2] ...
Ringo loads the script file and provides the argument via the system module's args array. The first element in the args array is the script file's name.
References