require_tree

Recursive Package like Module and JSON Loading for Nodejs

npm install require_tree
20 downloads in the last month

require_tree([path], [options])

Recursive Package like Module and JSON Loading for NodeJS

Build Status

Installation

npm install require_tree

Basic Usage

Given a directory structure as follows

- lib/
    - models/
        - User.js
    - controllers/
        - Login.js
    - utils/
        - index.js
        - specialUtility.js
    - config.json

You can import all these in a single require_tree statement and access them via hash syntax like a traditional OO Package

var app = require('require_tree').require_tree('lib');

// models.User is now accessable
     var user  = new app.models.User();

// JSON objects are accessed in the same manner
var configVal = app.config.myValue;

// index files are appended directly to the local root
app.utils.myIndexFunction();

// other files are appended within the same scope
var util = new app.utils.specialUtility();

Arguments

path: A standard path to a given directory to import. This parameter is optional and defaults to null

options: The options object accepts these properties:

locals: A user defined JS Object that will be made avialable to loaded modules

packages: An arbitrary object or existing package structure from another require_tree instance that will serve as the basis for the current require_tree instance

preserve_filenames: A boolean value instructing require_tree to preserve the filename in the package path structure. The default value is false note: This directive will be temporarily ignored and the filename used to name an unnamed function to support sloppy module.exports = function() {...} usage

Methods

The following methods are accessable from both the returned package structure and the module.parent.exports

getTree(path)

Returns a given package and it\'s descendants. Accepts both hash and path syntax

example:

// from application scope
tree = require('require_tree').require_tree('lib');
console.log( tree.require_tree.getTree('models') );

// from loaded module
console.log( module.parent.exports.getTree('models') );

addTree(path)

Recursively loads a new directory structure into the package structure of the current scope

example:

// from application scope
tree = require('require_tree').require_tree('lib');
tree.require_tree.addTree('otherLib');

// from loaded module
module.parent.exports.addTree('otherLib');

extendTree(object)

Merges a given package and it\'s descendants with the existing package structure.

example:

// from application scope
tree = require('require_tree').require_tree('lib');
eTree = require('require_tree').require_tree('lib2');
tree.require_tree.extendTree(eTree);

// from loaded module
eTree = require('require_tree').require_tree('lib2');
module.parent.exports.extendTree(eTree);

removeTree(path)

Removes a given package and it\'s descendants from the package strucure. Accepts both hash and path syntax.

Note: This will not remove loaded Modules from the Module Cache.

example:

// from application scope
tree = require('require_tree').require_tree('lib');
tree.require_tree.removeTree('models');

// from loaded module
module.parent.exports.removeTree('models');

on(name, callback, context)

Adds an event handler for a given event

example:

// -- will print contents of package to console when loading has completed
(rTree = require('require_tree')).on( 'completed', function(data) {
    console.log(data);
});

rTree.require_tree('./lib');

off(name, callback, context)

Removes an event handler for a given event

example:


(rTree = require('require_tree')).on( 'completed', function(data) {
    // -- will remove the event handler for further completed events.
    data.require_tree.off('completed');
    console.log(data);
});

rTree.require_tree('./lib');

trigger(name, ...)

Dispatches an event to all listeners

example:


(rTree = require('require_tree')).on( 'myEvent', function(data) {
    console.log(data);
});

// -- calling trigger will cause the above listener to capture and event
rTree.trigger('myEvent', {data:"hello world"});

Events

Event listeners may be added and removed using the on and off methods listed above the following events are dispatched by require_tree

completed

Triggered when require_tree has been called directly, passes package structure as it's data payload

changed

Triggered when addTree, removeTree or extendTree have been called with the following payload:

packages: the complete package structure in it's present state added: If present, will contain the tree that has been added. Passed on addTree or extendTree operations removed: If present will contain the tree that has been removed. Only passed on removeTree operations

Passing Data

By passing a JS Object to the locals param of theoptions object, you can set that Object for access from module.parent.exports.locals in your loaded Module\'s scope.

index.js:

var myMods = require_tree("lib", {locals:{"myArray":[1,2,3,4]}});

lib/myMod.js:

var passedArray = module.parent.exports.locals.myArray;
console.log(passedArray);

Nesting require_tree Calls

Making nested require_tree calls from within loaded Modules will create a new require_tree instance and Module Scope with a new package structure. Use the packages params of the options argument to pass in an exising object or package structure to inherit from.

example:

(function(global)
{
    // use require_tree to load a structure into a new scope
    // note that we pass in the packages object in the options for the new sub-tree
    global.config = require('require_tree').require_tree( '../subtree', {packages:{module.parent.exports.getPath('.')}});

    // our new tree will have inherited the parent require_tree packages
    console.log( global.config );
})(exports);

Building Data Structures

require_tree allows you to import JSON documents and treats each index file as a root element. This functionality allows you to create multiple index and data files to selectively build complex JSON data sets from static files.

- conf/
    - condition_1/
        - index.js
    - condition_2/
        - index.js
- lib/
    - config.js
- index.js

In the above diagram, we see a configure.js file and a conf structure. The intent here is to have build a config file based on the user environment much as we would build an application config using a configure script

lib/config.js

(function(global)
{
    // attempt to get passed data from locals Object
    var conditionValue = module.parent.exports.locals.condition || 1;
    // use require_tree to load a given structure into the current scope
    module.parent.exports.addTree( '../conf/condition_' +  conditionValue);
})(exports);

index.js:

config = require_tree("lib", {locals:{"condition":2}});

// config will now contain the dynmically generated JS object structure
console.log(config);

Accessing the Package Structure

While require_tree returns the loaded package Structure to the caller, it can be very useful to be aware of the Package Structure from within a loaded module require_tree exports the packages as exports.packages and includes a require_tree package containing the exported methods listed in theMethods section above.

From the Application Scope

example:

var tree = require('require_tree').require_tree('path/to/dir');

// using the `module.parent.exports.getTree` method
var otherObjectRef = tree.getTree('path.to.other.Object');
this.myRefInstance = new otherObjectRef();

// add another directory structure to the current package
tree.addTree('path/to/new/dir');
// access the new tree
console.log( tree.getTree('dir') );

// remove a directory structure to the current package
tree.removeTree('dir/subtree');
// access the updated tree
console.log( tree.getTree('dir') );

// remove a directory structure to the current package
tree.extendTree({dir:{newSubTree:{val1:"value1", val2:"value2"}}});
// tree 'dir' will now have 'newSubTree' nested
console.log( tree.getTree('dir') );

From Loaded Modules

example:

(function(global)
{
    // using the `module.parent.exports.getTree` method
    var otherObjectRef = module.parent.exports.getTree('path.to.other.Object');
    global.myModule = function() {
        this.myRefInstance = new otherObjectRef();
    }

    // add another directory structure to the current package
    module.parent.exports.addTree('path/to/new/dir');
    // access the new tree
    console.log( module.parent.exports.getTree('dir') )

    // remove a directory structure to the current package
    module.parent.exports.removeTree('dir/subtree');
    // access the updated tree
    console.log( module.parent.exports.getTree('dir') );

    // remove a directory structure to the current package
    module.parent.exports.extendTree({dir:{newSubTree:{val1:"value1", val2:"value2"}}});
    // tree 'dir' will now have 'newSubTree' nested
    console.log( module.parent.exports.getTree('dir') );
})(exports)
npm loves you