5

I need to be able to use require() on a dynamic relative path - meaning that the relative path needs to change depending on the current environment.

What is the best practice for this type of situation?

I thought of something like this:

var module = require(process.env.MY_MODULES_PATH + '/my-module');

However environment variables are not very convenient.

Are there other possibilities?

  • Maybe use package.json post-install script to set the environment variable for me?
  • Maybe there's a built in solution in node I don't know about?

EDIT

I just realized that this is a special case of require() "mocking". Is there a best practice for how to mock require() for unit-tests for example?

6
  • 3
    In any case you should use path.join(). Commented May 5, 2015 at 12:57
  • Will the module always be relative to the current path? For instance you could do require('../../some/directory/my-module'); to go up two directories and back down some/directory/my-module. Commented May 5, 2015 at 14:04
  • What exactly is inconvenient about environment variables? Is it just setting them correctly that's a problem? Commented May 5, 2015 at 14:32
  • it's inconvenient because it's something external to my code that could change at any time. I much prefer config files for example - they are much more obvious and intuitive Commented May 6, 2015 at 6:56
  • @Randy - no, I need to be able to route to different paths on each env, regardless of the current path. Commented May 6, 2015 at 10:29

3 Answers 3

1

MockedRequire.js

var path = require('path');

function MockedRequire(module) {
    return require(path.join('/path/to/modules', module));
}

module.exports = MockedRequire;

Use:

var mymodule = require('./MockedRequire.js')('mymodule');

To be honest I haven't actually tested this but it should work without issues.

Sign up to request clarification or add additional context in comments.

2 Comments

this does not solve the problem I described. I need to be able to control the /path/to/modules to be different on different environments. All you did was provide a module that does exactly what I already know...
You said you didn't want to use environment variables. So another option is to use a file with "settings". Well this could essentially be your settings file for changing the require path. So on System X you use this one where the path is /path/to/modules and on System Y you can use a similar file where the path is /other/path. Or if it's OS based then you could simply check the OS at require time (stackoverflow.com/questions/8683895/…). Based on your question you just want to be able to change the path. Here is one way.
1

Webpack needs to know what files to bundle at compile time, but expression only be given value in runtime, you need require.context:

/* If structure like:

    src -
         |
          -- index.js (where these code deploy)
         |
          -- assets - 
                     |
                      --img
*/  


let assetsPath = require.context('./assets/img', false, /\.(png|jpe?g|svg)$/); 

// See where is the image after bundling.
// console.log(assetsPath('./MyImage.png'));
// In fact you could put all the images you want in './assets/img', and access it by index: './otherImg.jpg' 
var newelement = {
    "id": doc.id,
    "background": assetsPath('./MyImage.png');
};

Comments

0

I would suggest using a configuration loader. It will select your path based on your NODE_ENV variable, but its much cleaner than what you suggested because you keep all of the environment specific config within a single external file.

Examples:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.