Large nodejs project structure - How to handle interdependencies

I have a nodejs project that is getting pretty big pretty fast. Due to my limited understanding of modules and requirements, I am sure that I can do some things to clear the code and structure.

<app dir> -app.js - <modules> -module1.js -module2.js - <routes> -route1.js -route2.js - <utilties> -utility1.js -utility2.js - <authentication> -local.js -basic.js -index.js 

My app.js is pretty dirty since I have dependencies between my files. IE I want to pass my models and authentication to my routes, utilities can be used with a bunch of things.

 var app = express(); ... // do express setup var authenticationStrategy = // get auth strategy from config var auth = require('./auth)(authenticationStrategy); var utility1 = require('./utilities/utility1.js'); var utility2 = require('./utilities/utility2.js'); var utilities = { utility1: utility1, utility2: utility2 } var Model1 = require('./models/model1')(utilities); var Model2 = require('./models/model2')(utility1); var models = { Model1: Model1, Model2: Model2 } // Dynamically import all routes fs.readdirSync('routes').forEach(function(file) { if (file[0] == '.') return; var route = file.substr(0, file.indexOf('.')); require('./routes/' + route)(app, models, utilities); }); ... etc 

Now I know that I can put index.js in each folder to clear things, but I still have to save things like utilities and pass them to other calls.

I can put each of them in lower modules only where necessary, but then I end up going up the directory structure with my query, which also seems messy, i.e.:

model1.js: var utility1 = require ('../utilities/utility1.js');

Basically, I believe that my problem is that modules in lower level folders depend on other modules in other folders. Since it seems to me that I should use all the dependencies in app.js and pass them to the required modules that they need.

Any advice. I have been trying to restructure this for a few days, and I just keep banging my head on the wall, because nothing I do really makes it better.

The best would be a good design for a node project that uses things like mongoose, express, w / custom modules. and show a good way to handle interdependencies between modules.

+7
source share
2 answers

Edit: https://github.com/gagle/node-getmod

I also had headaches to properly structure my first real BIG node.js project. The biggest problem you are facing is the relative path used in require() calls. This is a pain because these paths refer to the current file, so you typically have these paths:

 ../../../a.js ./a/b/c/a.js ../../a/b/c/a.js 

They all point to the same file. This is inhuman. Hard to read, hard to maintain.

You cannot place your modules inside the node_modules directory and simply require the name of the module ( require("a") ), because this directory is used by third-party modules. If you need to perform maintenance tasks, for example, perform a complete update of all modules, remove them and reinstall them, etc., they are extremely easy and safe. If you post your modules, you will have a big problem if you do not have good documentation and you work in a medium-sized team.

A few hours later I finished this technique:

Local NodeJS modules for complex application structures

With the mod() function, you have good control over your modules. In my real and BIG project, my mod function is as follows:

 "use strict"; var serverType = require ("./server-type"); global.mod = function (file){ var dir = file.substring (0, file.search (/\/|\\/)); if (!dir) dir = file; if (dir === "browser" || dir === "common" || dir === "mobile" || dir === "stream"){ //Relative from the web directory return require ("../" + file); } if (dir === "api"){ //Relative from the api directory return require ("../../" + (file === "api" || file === "api/latest" ? file : "api/" + APP.versions.api + "/" + file.substring (4))); } if (dir === "build"){ //Relative from the build directory return require ("../../" + file); } //Tries to load the module inside browser or mobile directories depending on //the cwd return require ("../" + serverType () + "/" + file); }; 

If I call mod("api") , it returns my api module, the core of my website.

If I call mod("common/db") , it returns a db wrapper.

If I call mod("build/...") , it returns the module needed to create static assets (css and js compilation)

etc.


Now you misunderstand how modules should be used. Example:

 var utility1 = require('./utilities/utility1.js'); var utility2 = require('./utilities/utility2.js'); var utilities = { utility1: utility1, utility2: utility2 } var Model1 = require('./models/model1')(utilities); var Model2 = require('./models/model2')(utility1); var models = { Model1: Model1, Model2: Model2 } 

Here you pass the utility module to another module, and this is not required. You can get the utilities module from the modules model1 and model2.

A very simple example:

A depends on B

 //app.js require ("./a").a (); //a.js var b = require ("./b"); module.exports = { a: function (){ bb ("I'm A"); } }; //b.js module.exports = { b: function (msg){ console.log ("B says: " + msg); } }; 

You do not need to do this:

 //app.js var b = require ("./b"); require ("./a").a (b); //a.js module.exports = { a: function (b){ bb ("I'm A"); } }; //b.js module.exports = { b: function (msg){ console.log ("B says: " + msg); } }; 

Is this what you are looking for?

+2
source

1- create a file in the root of the project, call its settings.js

2- add this code inside this file

 module.exports = { POST_MAX_SIZE : 40 , //MB UPLOAD_MAX_FILE_SIZE: 40, //MB PROJECT_DIR : __dirname }; 

3- inside node_modules create a new module name, these are “settings”, and write this code inside index.js module:

 module.exports = require("../../settings"); 

4- and anytime you want your project directory to use only

 var settings = require("settings"); settings.PROJECT_DIR; 

this way you will have all the project directories regarding this file;)

+1
source

All Articles