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.)
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.
The double dots refer to the parent directory; I'm not sure that there is other associated terminology or if there is an easier way to express what you wrote.
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.
+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.
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.
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.
That was point of the article: npm is not a valid option for various reasons, but it should be easier for applications to organize the source code in multiple directories which you then tarball.
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
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.
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.
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.
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?
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.
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).
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...
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.
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.
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?
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.
Consider:
Versus: 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.)