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.
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.
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'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 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?
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.)
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.
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.
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...
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.
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.
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.
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.
43 comments
[ 3.9 ms ] story [ 94.7 ms ] threadThen 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
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.
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).
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
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.)
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
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.Usage is as follows:
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.
https://github.com/hellopat/prequire
[1] https://github.com/FungusHumungus/pongular
var rootDir = process.cwd(); var config = require(rootDir + '/server/config');
And so forth.
Applications can be decoupled into interoperable components. Separate modules for configuration, controllers, routing, etc.
Separate concerns into modules.