0

My folder structure:

-base directory  
--app.js

--models  
---property.js  

--routers  
---api  
----v1
-----properties.js  

My Problem

In routers/api/v1/properties.js, how do I do get the base directory so I can stop doing this:

const Property = require('../../../models/property');

I want to remove the repetitive ../../../

My Current Solution

In my app.js, I add a line:

global.__basedir = __dirname;

And then in routers/api/v1/properties.js,

const path = require('path');
const Property = require(__basedir + '/models/property');

So what do you think? Are there pitfalls to this method? Is this the best way to do this?

taptipblard
  • 491
  • 1
  • 7
  • 15
  • You can use [`process.cwd()`](https://nodejs.org/api/process.html#process_process_cwd), assuming that `app.js` is the entry point. See [What's the difference between process.cwd() vs __dirname?](https://stackoverflow.com/q/9874382/1541563) – Patrick Roberts Feb 06 '19 at 23:07
  • [How to make node.js require absolute? (instead of relative)](https://stackoverflow.com/questions/10860244/how-to-make-node-js-require-absolute-instead-of-relative/24630974#24630974) – Felix Kling Feb 06 '19 at 23:09
  • Also for a cross platform Node.js application, you should avoid concatenating strings to create relative paths, and use `path.join()` or `path.resolve()` from the [`path`](https://nodejs.org/api/path.htm) module depending on your use-case. – Patrick Roberts Feb 06 '19 at 23:10
  • In addition to the ways mentioned above, you can also try [`module.createRequireFromPath(filename)`](https://nodejs.org/api/modules.html#modules_module_createrequirefrompath_filename) (needs Node.js 10 at least). – vsemozhebuty Feb 06 '19 at 23:48
  • Hi guys! Thanks for the input. I went for process.cwd() since it seems like the most official nodejs thing to do. I am also using path.join now. – taptipblard Feb 10 '19 at 06:33

1 Answers1

2

Using a 3rd party module:

Use app-root-path module (https://www.npmjs.com/package/app-root-path).

const appRoot = require('app-root-path');
const myModule = require(appRoot + '/lib/my-module.js');

Update:

Using built-in Node functionality

You can set NODE_PATH environment variable to your base directory. Then you should be able to require modules relative to the NODE_PATH from anywhere in your project.

e.g,

Let's say your file is app.js and has the following content,

const Property = require('models/property');

You could run it as follows (replace /path/to/base/directory with the path to the base directory):

$ NODE_PATH=/path/to/base/directory node app.js

You can read more about it in the documentation here: https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders

It's important to know that most IDEs don't know/care about the NODE_PATH variable (for example VSCode), therefore intellisense will break because IDE doesn't know where it can find the module models/property. But it should be fixable using IDE-specific configurations. See here: https://github.com/microsoft/vscode/issues/28707#issuecomment-308513626

Deepal
  • 1,729
  • 5
  • 24
  • 34