Search code examples
javascriptnode.jsrequirenode-modules

How to require deep nested NodeJS modules?


I have the following application structure:

application
|- config
|----- config.js
|- routes
|------ api
|-----------router.js 
|- Application.js
|- package.json

In /routes/api/router.js module I need to require /config/config.js file and do the following:

require('../../config/config.js');

I found the code above ugly and want to make it more pretty. Also if I move /routes/api/router.js to another folder I have to refactor all requires. What is the best practices to require that modules and is it possible to require config.js from application folder root, something like the following:

require('/config/config.js');

Thanks.


Solution

  • There are a few ways to get around this problem. One is to put all your shared code (like config.js) in a directory under node_modules (using lib here in case you want to have directories other than config in there):

    application
    |- node_modules
    |----- lib
    |---------- config
    |-------------- config.js
    |- routes
    |------ api
    |-----------router.js 
    |- Application.js
    |- package.json
    

    So then you could require config.js using require( 'lib/config/config.js' ).

    Alternatively, you could create a lib symlink in node_modules and link it to lib in your application directory structure:

    application
    |- node_modules
    |----- lib -> ../../lib
    |- lib
    |------ config
    |---------- config.js
    |- routes
    |------ api
    |-----------router.js 
    |- Application.js
    |- package.json
    

    One other alternative, which unfortunately is discouraged by the node docs, is to use NODE_PATH which lets you specify directories that node's require() algorithm should look into. Following the same pattern as above with lib, you would do:

    application
    |- lib
    |------ config
    |---------- config.js
    |- routes
    |------ api
    |-----------router.js 
    |- Application.js
    |- package.json
    

    and set NODE_PATH equal to $path_to_application/lib.

    UPDATE

    Found this great discussion on the topic which includes the options above as well as a few other ones.