简体   繁体   中英

Node.js - How to get relative require paths?

I have a module that works like so:

/helpers/importer/Import.js

function importer(requiredModulePath, toImport) {
  requiredModulePath = requiredModulePath.replace('{env}', browser.params.env);
  var requiredModule = require(requiredModulePath);

  return requiredModule[toImport] || requiredModule.default || requiredModule;
}

module.exports = importer;

I use this to import module properties dynamically, such as the following "URLs" module:

/example/URLs.js

module.exports = {
  default: 'http://google.com',
  a: 'http://a.com',
  b: 'http://c.com'
};

And I do this like so:

/example/myExecutingModule.js

var Import = require('../helpers/importer/Import');
//var URL = Import('./URLs');             //This path does not work
var URL = Import('../../example/URLs');   //This path does work, as the URL is relative to Import.js 
[ ... ]

My problem here is that, unlike everyone else on stack overflow, who wants absolute paths in their requires, I want the opposite. I would like to supply the same path to my Import function that I would supply to require -- the one that is relative to myExecutingModule.js, in this case: './URLs'. However, it seems like my "importer" function has closure over the "require" function which is relative to its path. Is there any way to write it such that "require" will be relative to the module calling importer()? As I type this, it feels like the only way would be to pass "require" into the Import.js module, which I feel is kind of... ridiculous

EDIT: After thinking on this further I am guessing that the answer involves giving Import closure over the calling module's require function, like so:

var Import = require('../helpers/Import')(require);

And then the export in Import.js will be

module.exports = function (require) { [...] return importer; };

Causing "require" within the importer function to be the actual require function that the calling module would have used. I have not tried this yet, and I'm holding out for a better answer, so I will leave this question open for now

您可以使用__dirname设置为当前模块所在的目录。例如: __dirname + '/URLs'

Try the local-modules package. I've used it in production on node 0.10 and io.js 2.3 so far without any problems.

https://www.npmjs.com/package/local-modules

https://github.com/intesso/local-modules

This is the solution I am using now. Passing "require" to the Import module from the calling module, so that it is importing relative to the calling module's location.

var import = require('../helpers/Import')(require);
var URL = import('./URLs');

And then Import.js uses the calling module's require instead of its own:

module.exports = function (require) {
  function importer(requiredModulePath) {

    [ ... ]

    var requiredModule = require(requiredModulePath);
    return requiredModule[toImport] || requiredModule.default || requiredModule;
  }

  return importer;
};

Feels a little weird but, what can ya do

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM