Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping require

Given

3 Node.js projects Main - Framework - Repositories

Main has the two other projects connected via npm link.

In a test i wrapped the require in a method. I've got some problems resolving linked projects (details see below)

Simplified code looks like this:

module.export.resolve = function(file){
[...]//Some more logik to handle relative pathes
return require(file)
}

This works fine in most scenarios. I also worked out to get handled with relatives pathes (looking up for caller and apply pathes based on this path)

Now this is in Project Framework which is linked (npm link) to Project Main. Project main has also Project Repositories linked.

Now in Project Main i have:

require('ProjectRepositories/foo') // Works as expected
myRequire.resolve('ProjectRepositories/foo') //  Returns MODULE_NOT_FOUND "Cannot find module 'ProjectRepositories/foo'

I assume the problem is that Repositories Project ist not linked in the Framework Project. But is there an other way than linking them ?

I'd prefer to have less dependencies. Any hints on that?

like image 772
Boas Enkler Avatar asked Nov 10 '22 19:11

Boas Enkler


1 Answers

You are absolutely correct in that the reason why the Project Framework resolve does not work is because the requireFn being used from within that project only knows about the modules installed in that framework. This is because when you require a javascript file, node evaluates the script within the context of the module, and not the context of the current project (this is how dependency modules' requires work when from your top-level script).

What you can do, however, is provide a way for the framework resolver to use a user-specified require function to do its work, once it has transformed the paths.

module.exports.resolve = function(file, resolver) {
  //Some more logik to handle relative pathes
  resolver = typeof resolver == 'function' ? resolver : require;
  return resolver(file)
}

Now in your code, you could do

myRequire.resolve('ProjectRepositories/foo', require);

So now your Project Main require will be used to resolve the file.

You can also take this a step further if you want and have the module be stateful and remember the resolver it's supposed to use.

var _requireFn = require;

module.exports = {
  resolve: resolve,
  setRequireFn: setRequireFn
};

function resolve(path) {
  return _requireFn(path);
}

function setRequireFn(requireFn) {
  _requireFn = requireFn;
}

On another note, I would be careful about using the term resolve because in node that's semantically used for looking up the correct file path to be required, a la require.resolve.

Finally, in terms of minimizing dependencies, I'd recommend including your subprojects in npm using github repos. This has worked pretty well for me in the past, unless your two subrepos are in a constant state of flux. See the install docs for more info.

like image 112
Travis Kaufman Avatar answered Nov 14 '22 22:11

Travis Kaufman