279

I would like to 'require' my files always by the root of my project and not relative to the current module.

For example, if you look at Express.js' app.js line 6, you will see

express = require('../../') 

That's really bad, IMO. Imagine I would like to put all my examples closer to the root only by one level. That would be impossible, because I would have to update more than 30 examples and many times within each example. To this:

express = require('../') 

My solution would be to have a special case for root based: if a string starts with an $ then it's relative to the root folder of the project.

What can I do?

Update 2

Now I'm using RequireJS which allows you to write in one way and works both on client and on server. RequireJS also allows you to create custom paths.

Update 3

Now I moved to Webpack and Gulp.js and I use enhanced-require to handle modules on the server side. See here for the rationale: http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/

3
  • If you ever decide to use an explicit root path constant/variable, this answer works for that. The solution uses a tiny github module to determine the root path. Commented Jun 11, 2015 at 18:33
  • 2
    gist.github.com/branneman/8048520 Commented May 26, 2016 at 7:15
  • The link at the end is (effectively) broken: It redirects to a generic page. Commented Feb 23, 2023 at 16:19

39 Answers 39

1
2
1

I was having trouble with this same issue, so I wrote a package called include.

Include handles figuring out your project's root folder by way of locating your package.json file, then passes the path argument you give it to the native require() without all of the relative path mess. I imagine this not as a replacement for require(), but a tool for requiring handling non-packaged / non-third-party files or libraries. Something like

var async = require('async'), foo = include('lib/path/to/foo') 
Sign up to request clarification or add additional context in comments.

Comments

1

In simple lines, you can call your own folder as module:

For that we need: global and app-module-path module

Here "App-module-path" is the module. It enables you to add additional directories to the Node.js module search path. And "global" is anything that you attach to this object will be available everywhere in your app.

Now take a look at this snippet:

global.appBasePath = __dirname; require('app-module-path').addPath(appBasePath); 

__dirname is the current running directory of Node.js. You can give your own path here to search the path for module.

Comments

0

Some time ago, I created a module for loading modules relative to pre-defined paths.

https://github.com/raaymax/irequire

You can use it instead of 'require'.

irequire.prefix('controllers',join.path(__dirname,'app/master')); var adminUsersCtrl = irequire("controllers:admin/users"); var net = irequire('net'); 

Comments

0

Whilst these answers work, they do not address the problem with npm test.

If, for example, I create a global variable in server.js, it will not be set for my test suite execution.

To set a global appRoot variable that will avoid the ../../../ problem and will be available in both npm start and npm test, see:

Mocha tests with extra options or parameters

Note that this is the new official Mocha solution.

1 Comment

If you don't use globals - like a good developer - it works fine. I don't like adding bootstrap to my projects, it's a recepie for global abuse.
0

Try using asapp:

npm install --save asapp

var { controller, helper, middleware, route, schema, model, APP, ROOT } = require('asapp') 

controller('home') instead require('../../controllers/home)

Comments

0

My method of achieving this is to create "local link modules".

Take for example the folder structure of

db ¬ models ¬ index.js migrations seed config.json routes ¬ index.js user ¬ index.js 

If from ./routes/user/index.js I want to access /db/models/index.js, I'd be writing:

require('../../db/models/index.js') 

To make the /db/models/index.js accessible from everywhere, I create a folder inside the db folder named _module_, this contains a package.json and a main.js file.

# package.json { "name": "db", <-- change this to what you want your require name to be "version": "1.0.0", "description": "", "author": "", "repository": {}, "main": "main.js" } 
// main.js module.exports = require('../../db/models/index'); 

The path in main.js must be relative as if the file is in node_modules, like

node_modules ¬ db ¬ main.js 

You can then run npm install ./db/_module_ and this will copy the files in ./db/_module_ to ./node_modules/db creating an entry under dependencies in the app's package.json like

"db": "file:db/_module_" 

You can now use this package from anywhere by

const db = require('db'); 

This automatically installs with the rest of your modules when you run npm install, works cross-platform (no symbolic links), and doesn't require any third-party packages.

Comments

0

Since none of the proposed solutions was quite as concise as I wanted, I wanted to share mine here.

I was looking for a solution that doesn't not 'require' anything additional, no modules, no package.json modifications, no environment variables, no external dependencies, minimal CPU cycles, etc.

...so I came up with this:

global.dir = process.cwd();

I do this once when the app loads. Obviously, you can modify the path by adding a subdirectory and/or adding '/..' which will send you up or down the directory tree as needed.

All my includes, in all files, are in this format:

const myFn = require(global.dir + '/js/myDir/myFn'); 

Comments

-1

I don't think you need to solve this in the manner you described. Just use sed if you want to change the same string in a large amount of files. In your example,

find . -name "*.js" -exec sed -i 's/\.\.\/\.\.\//\.\.\//g' {} + 

would have ../../ changed to ../

Alternatively, you can require a configuration file that stores a variable containing the path to the library. If you store the following as config.js in the example directory

var config = {}; config.path = '../../'; 

and in your example file

myConfiguration = require('./config'); express = require(config.path); 

You'll be able to control the configuration for every example from one file.

It's really just personal preference.

8 Comments

well but if in one example it uses ../../ to another module in the same example and not to the root then it breaks all the code. Yes you could do the path variable but that's not a clean way to do IMO. If you move files from here to there this is not that clean. And just take a look at "../../" how descriptive that is compared to 'express'. or '../../../my/config' compared to '/my/config', there is no comparation..
By the way you would have to require config in each folder you use and the same problem would happen. If you change a folder you will have to change require('./config') to require('../../config'), same problem again.. lol
Change the expression if you don't want it to match every occurrence of "../../". Here's one that will only match that line you provided: "s/express = require('\.\.\/\.\.\/')/express = require('\.\.\/')/"
this is just one module in the parent folder, but in a real world project you can't just do like that. There would be plenty of different parent folder and modules and this relative pathing it's making me crazy. In my way you could easily replace the full path to the new one across the whole project.
well I just made a npm module that do the trick (search.npmjs.org/#/r) I put "var r = require('r').r" at the begining of each module and then all the requires will be r(...). if the first character it's ">" ex. r('>/my/sub/folder/') then it's relative to the root folder of my project. This is the best thing I could come with for now
|
-2

Many good answers here already. That just shows this is a common problem without clear-cut best solution. Best would be native support in Node.js of course. Here's what I use currently:

const r = p => require (process.cwd() + p); let see = r ('/Subs/SubA/someFile.js' ); let see2 = r ('/Subs/SubB/someFile2.js'); ... 

I like this solution because the requires-section becomes shorter, no need to type 'require' many times. The main benefit of absolute paths is you can copy them from file to file without having to adjust them like you would with relative paths. Therefore copying also the extra one-liner arrow-function 'r()' is not too much extra work either. And no need to import extra npm-dependencies just to accomplish this very simple task.

Comments

1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.