How I Work Around The require(“../../../../../../../”) Problem In NodeJS
lostechies.com
lostechies.com
Consider:
require('foo');
Versus: require('./foo');
If I find that a module is becoming popular, I may turn it into an npm module by moving it to it's own folder and adding a package.json, then using npm's bundledDependencies property to inform npm that it lives locally.(edit: Note that I've shifted my perspective on the module when this happens. The shift is from "This code is in a separate module to keep my application organized" to "This code is in a separate module because it has some logical independence from the application.")
If the module needed even more independence, I'd move it to it's own git repo and create an internal mirror of the npm repo so that it can be discovered internally, and unbundle it from my app. (I could see this happening especially with larger teams, or teams that embrace the "module all the things" philosophy.)
And of course, there's always the possibility of moving the module out to the public npm repos and hosting it there.
I've never had require with relative paths of more than two or three "double dots". (Note to self: Look up what those things are called formally.)
require('foo');
and application files like: require('./foo.js'); //.js extensionAdding a relative path to a *PATH variable is clever, elegant, useful, and uncommon. It resolves a problem not directly (by changing how 'require' works internally), but indirectly, aka "working around" it.
Then your other project in the same file system can just require like a first class public npm module.
npm link lib
link -s lib node_modules/lib
Then: require('lib/models/user')
No matter where you are.Usage is as follows:
var pRequire("./projectRequire")(rootPathOfYourProject);
var MyModule = pRequire("~/lib/foo/bar/myModule");
It doesn't really buy you anything over `require("nameOfYourPackage/path/to/module")`, but I like the consistent "~" prefix across projects using the same scheme.Moving things to their own NPM package is a great solution when its something re-usable that logically makes sense to exist on it's own, but that isn't the case most of the time.
My usual idiom is to do two things:
1. Part of my boilerplate at the top of every JS file is something like this:
var path = require('path');
var HOMEDIR = path.join(__dirname,'..','..');
where `__dirname` is the built-in variable that names the directory that contains the current file, and `'..','..'` is the requisite number of steps up the directory tree to reach the root of the project.From there is it is simply:
var foo = require(path.join(HOMEDIR,'lib','foo'));
var bar = require(path.join(HOMEDIR,'lib','foo','bar'));
to load an arbitrary file within the project.2. Long before I got to 8 levels deep in the directory tree I'd create a separate npm module to bundle the code together in a less spaghetti fashion.
For what it's worth, I typically use a branch on a private GitHub repository for my "private" modules. I.e., the master branch has the source code, and another (say, `npm-v1.2.3`) has the npm package of it.
For example, if your package is called my-node-module and you have something in my-node-module/lib/app/dir/thingy/wotsit/jimminy.js, it can reference something in my-node-module/lib/server/alf.js by simply going
require("my-node-module/lib/server/alf.js");
There's no need for the relative path at all. It's possible that this only works if your package is in an node_modules directory (which it will be if it's installed as a dependency), but I always symlink my development directory to node_modules anyway.Another approach, which I favor now, is to place modules directly into the default locations, such as /usr/lib/share/perl5 and etc.--usually there are a number of paths Perl looks at by default. It's then just a matter of saying 'use MyModule;' in code.
Is node.js similar, in having one or more include paths set by default, and could files be put there, to where you never have to refer to something by relative location again?
I've never worked on a Node project with directories that nested more than 3 or 4 levels deep, so I don't see this as a "problem" (but maybe the article makes a case that it is).
Applications can be decoupled into interoperable components. Separate modules for configuration, controllers, routing, etc.
Separate concerns into modules.
https://www.npmjs.org/doc/install.html
You can also use your own npm registy using `--registry`:
var rootDir = process.cwd(); var config = require(rootDir + '/server/config');
And so forth.