2

I am developing an NPM package. Now I want to know the easiest way to get the root of the project which utilizes my custom package.

Within my package itself it is pretty easy to get the root in node.js like so:

__dirname

This points to the root of my package itself though. I would like to get the root of the project which actually performed the npm install of my package though.

Obviously, I could simply go up from the node_modules directory and assume that the root directory is there but this sounds really bad.

Is there a standard way to achieve this?

Erik
  • 503
  • 1
  • 7
  • 26
Stephan-v
  • 19,255
  • 31
  • 115
  • 201

3 Answers3

3

you could use app-root-path which is an npm module and its pretty neat.

npm i -S app-root-path

after that just do

var reqlib = require('app-root-path').require;
var myModule = reqlib('/lib/my-module.js');
miqe
  • 3,209
  • 2
  • 28
  • 36
  • @Stephan-v it works like you thought , just by finding the root `node_modules` directory. – miqe May 26 '18 at 16:38
2

You can use the info from: require.main

The Module object representing the entry script loaded when the Node.js process launched. See "Accessing the main module".

const path = require('path');
console.log(path.dirname(require.main.filename));

Having this folder structure:

/app
  entry.js
  node_modules/
    my-package/
      index.js

app/entry.js

const myPackage = require('my-package');

app/node_modules/my-package/index.js

const path = require('path');
console.log(path.dirname(require.main.filename));

And when you call: node entry.js

You will get: /app printed to stdout.

Marcos Casagrande
  • 37,983
  • 8
  • 84
  • 98
  • 4
    This leaves me with the root of the package itself, not the root of the project which uses my package. – Stephan-v May 26 '18 at 16:25
  • How are you running node? are you calling your package directly? – Marcos Casagrande May 26 '18 at 16:26
  • It it being called as an executable through npm scripts in my main project. In my custom package I have set up a `bin` property in the `package.json`. – Stephan-v May 26 '18 at 16:27
  • Just added: `path.dirname(require.main.filename)` to any package I have in `node_modules` and it's printing my project root. – Marcos Casagrande May 26 '18 at 16:28
  • There is no way it isn't working, you're doing something wrong, `require.main.filename` contains the entry point, unless your entry point isn't in the root of your project, you have something else going on. Post your directory structure and where is your entry point. – Marcos Casagrande May 26 '18 at 16:31
  • It fails because I used `npm link` which create a symlink for local development of my package. I am unsure on how to handle this though. – Stephan-v May 26 '18 at 16:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/171837/discussion-between-marcos-casagrande-and-stephan-v). – Marcos Casagrande May 26 '18 at 16:37
  • for some reason this gives me the bin folder in node_modules when running tests – Alko Jul 06 '20 at 07:51
2

KISS

const fullPath = path.dirname(require.main.filename);
const regexResp = /^(.*?)node_modules/.exec(fullPath);
const appRoot = regexResp ? regexResp[1] : fullPath;
console.log(appRoot); // outputs the directory which is the root of this project
Seph Reed
  • 8,797
  • 11
  • 60
  • 125