
How I Work Around The require(“../../../../../../../”) Problem In NodeJS - docluv
http://lostechies.com/derickbailey/2014/02/20/how-i-work-around-the-require-problem-in-nodejs/
======
jt2190
For me, a relative path in a require statement signifies that the required
code is a part of the application itself.

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.)

~~~
2mur
If find it's easier to distinguish modules from files by requiring modules
like:

    
    
      require('foo');
    

and application files like:

    
    
      require('./foo.js'); //.js extension

~~~
qubyte
Imagine if you're requiring that local module throughout your codebase. Now
suppose that the module has become large enough to be come a directory. All
those requires with the .js extension will break! If you leave it off, then no
problem. Always avoid adding the .js.

------
secoif
Anyone with this problem is most likely working on a horrible monolith. You
have far too much nesting and you're simply hiding the symptoms of a greater
problem. Flat > nested. Simple > complex. Law of demeter also applies to
reaching and in/out of folders. Break your app into more smaller modules
rather than sweeping your mess under the rug.

~~~
ianstormtaylor
+100 — NODE_PATH actually ends up being an anti-pattern because all of those
internal modules are still not versionable. Instead, use a private NPM
registry and just publish everything separately.

------
heydenberk
Setting an environment variable to include a directory in which you have
libraries that you need to use across your application is not a workaround.
It's using a feature.

~~~
mcgwiz
So? Asking earnestly, what exactly is your point? That the title offends you
because it uses the phrase "work around"?

Adding 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.

------
tlarkworthy
can't you install a private npm module by npm link? That won't touch the npm
servers [1].

Then your other project in the same file system can just require like a first
class public npm module.

[1] [https://www.npmjs.org/doc/cli/npm-
link.html](https://www.npmjs.org/doc/cli/npm-link.html)

~~~
royjacobs
How do you go about setting these links when you freshly checked out a project
through source control? There is no "npm link all", is there?

~~~
clux
[https://github.com/clux/symlink](https://github.com/clux/symlink)

------
eldude
Put one of the following in your package.json "postinstall" hook:

    
    
        npm link lib
        link -s lib node_modules/lib
    

Then:

    
    
        require('lib/models/user')
    

No matter where you are.

------
jdc0589
There are lots of workarounds. My preferred workaround isn't especially good,
but it keeps me sane since I also hate having giant relative paths.
[https://gist.github.com/jdc0589/9115898](https://gist.github.com/jdc0589/9115898)

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.

------
alexandere
[http://webcache.googleusercontent.com/search?q=cache:http://...](http://webcache.googleusercontent.com/search?q=cache:http://lostechies.com/derickbailey/2014/02/20/how-
i-work-around-the-require-problem-in-nodejs/&strip=1)

------
rodw
Am I the only one that doesn't find this a problem?

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.

------
kybernetikos
While I don't personally do this - I try to follow node idiom of having each
package be a relatively thin layer of functionality and having packages depend
on each other, I believe that you don't need to use relative paths if you
don't want to.

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.

------
joel_perl_prog
I've done this in the past on *nix systems, for Perl. I modified PERL5LIB from
my .bashrc file, so that my project lib was looked for by default. This,
rather than having to put 'use lib '../../../yikes/ugly' ahead of any
inclusion of project modules.

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?

------
ahdinosaur
I work around this problem in a couple projects by putting my code in modular
directories in ./src/node_modules. no npm magic, no having to make symlinks or
change path, just plain node. it also makes it very easy to publish your
modules when you are ready, just take the module directory out, give it a
package.json, npm publish the module, npm install --save the module back in
the project.

------
2mur
That is a code smell. node and require works really great with small modules.
npm link in development, tarball up and scp to your box for deployment.

------
shtylman
The fix for this is to use a module. Simple. Not a problem.

------
Touche
Article appears to be down.

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).

------
dreamdu5t
Your project is horribly architected if you need to do relative requires this
deep.

Applications can be decoupled into interoperable components. Separate modules
for configuration, controllers, routing, etc.

Separate concerns into modules.

------
moron4hire
This is half of why I much prefer .NET's namespacing. The other half is not
having to declare every single thing a file full of code exports for use.

------
awinder
I had this similar problem, but I solved it in a different way by creating a
module outside of the node_modules folder, and putting a symlink in the
node_modules folder. Read here to see how I broke this down
[http://winder.ws/blog/2013/10/15/structuring-local-node-
modu...](http://winder.ws/blog/2013/10/15/structuring-local-node-modules/)

------
etler
I think the best solution for this would be having a private npm server. With
npm's recent incorporation and funding, I have a feeling that is going to be
coming soon. It's helpful even for small companies, but once you have multiple
internal projects all with inter-dependencies that can't be put out
publically, it's pretty much a must.

------
jt2190
Google Cache (text only):
[http://webcache.googleusercontent.com/search?q=cache:http://...](http://webcache.googleusercontent.com/search?q=cache:http://lostechies.com/derickbailey/2014/02/20/how-
i-work-around-the-require-problem-in-nodejs/&es_sm=91&strip=1)

------
andypants
You don't have to make your code public if you want to use npm. You can use
your own private npm repo. You can use npm to install packages from private
git repos directly. You can use `npm link`. I'm sure there are a dozen more
ways.

------
hippich
I am not sure all your private code on git should be publicly accessible.
Wouldn't it be possible to point dependency to private in-house GIT
repository?

~~~
agilebyte
That is the option (g) here:

[https://www.npmjs.org/doc/install.html](https://www.npmjs.org/doc/install.html)

You can also use your own npm registy using `--registry`:

[https://www.npmjs.org/doc/misc/npm-
registry.html](https://www.npmjs.org/doc/misc/npm-registry.html)

------
hellopat
I made a module to solve this issue a while back.

[https://github.com/hellopat/prequire](https://github.com/hellopat/prequire)

------
wookimiii
Isn't it possible to use private git repos to install packages? Why not just
install packages from git instead of publishing to npm.

------
arxpoetica
A simple convention, as long as you know the process root:

var rootDir = process.cwd(); var config = require(rootDir + '/server/config');

And so forth.

------
unwind
The article seems to be missing crucial examples, making it very hard to read
and follow. :/

------
nilgradisnik
If you use requirejs for node, defining paths in requirejs.config solves this
problem too.

------
weavie
I've been using the AngularJS dependency injection module for all my
application code, [1] which means I am now only requiring libraries. I find it
makes for much cleaner code and easier to test as well.

[1]
[https://github.com/FungusHumungus/pongular](https://github.com/FungusHumungus/pongular)

------
jbeja
How this would work with browserify?

