Strider
Strider

Reputation: 402

Node.js package self-reference

Can package require itself and its subsystems?

For instance there is module: src/deep/path/to/module.js which need to require src/another/module.js

Instead of:

require('./../../../another/module.js');

Can one just:

require('<self>/another/module.js');

?

For instance this might be useful in testing: test unit can reference its test object without long up-and-down-style path.

I have two considerations (but they do not satisfies this issue completely):

  1. If package is already in node_modules folder it can reference to itself by its canonical name (that in its package.json).

  2. Package can create symlink to itself in its own node_modules folder (sic!). Haven't try it yet, possible will lead to infinite loop in some resolving cases.

Upvotes: 5

Views: 5042

Answers (3)

Andrew_1510
Andrew_1510

Reputation: 13526

Solution 1

Split it to different sub-projects, put each one into different folders. As an example:

  sub.project.1/  
  sub.project.2/

in sub.project.1/

  # cd ../sub.project.1
  npm link

  # cd ../sub.project.2
  npm link sub.project.1

Then in sub.project.2 you can do it simply:

var something = require("sub.project.1")

This can remove the '../../...' relative path.

Note: it can be done in same folder/project, by doing this, in the sub folders, the project self can be easily referred. For example when both sub.project.1 and sub.project.2 replaced by my.project. And of course, all the names should be the name in package.json initialized by npm.

Solution 2

Create a link in the folder node_modules/

  # cd node_modules
  ln  -s ..  myProjectRootDir
  #
  # where: .. : means parent directory in linux shell
  # '#' means comments in linux shell
  # 

Then it can be used under same level directory trees:

  var something = require("myProjectRootDir/path/to/js/file")

Thus the "../../..." can change to path read more easily. And if myProjectRootDir happens to be the project name and package name in package.json, it's ok.

Solution 3

There are npm packages: require-self, install-self, they do the similar things.

Solution 4

Write a new .js file where it's easy to require, then put all the annoying relative references into it.

For example write it at node_modules/mymods.js

  // mymod.js
  module.exports.mod_one = require("../path/to/mod/one.js"); 
  //...

Then require('mymod') can gives all the other modules. This is not the best solution, all references of requiring need to be doing by hand. But it's a single file, so it's manageable, and centralize the references for future deployments.

One of the cons of this solution is, if you put it in node_modules/ folder and this folder is ignored in git repository, you need to take care when pushing or branching the git repo.

When deleting the node_modules folder, the file can also be deleted by accidents.

There could be more solutions I don't know.

Upvotes: 1

arb
arb

Reputation: 7863

I often use process.cwd() to make things like this a little more manageable. This returns where the node application is actually running from and lets you create the path in a little cleaner fashion.

Something maybe like var x = require(process.cwd() + '/lib/module')

Without seeing exactly what you're trying to do; I'm not sure if this will be helpful, but you can do things like var connect = require('express/connect') as well. Basically you can pass an installed local module, and then create paths off of it as well.

Upvotes: 0

maček
maček

Reputation: 77778

Well you can shorten it a little bit. You don't need the leading ./ in this case

require("../../../another/module.js");

And a little further by removing the trailing .js

require("../../../another/module");

Another answer is suggesting the use of process.cwd() but be very careful with this. Your require calls will only work if the app is initialized from the same directory.


From the sounds of it though, 4 directories is already pretty deep. You might want to considering fragmenting your large project into smaller, single-purpose modules. We would need more information on the project to know if that was the right decision though.

Upvotes: 0

Related Questions