Martin Thompson
Martin Thompson

Reputation: 3755

Unable to require folder in nodejs

I'm a bit baffled with this. This is the first time I have tried to require a folder instead of just a .js file. There is only one file in that directory for now.

Folder: cfg , File: config.js ( in the cfg folder )

This works:

var file = require('./cfg/config');
console.log(file);

This fails:

var folder = require('./cfg');
console.log(folder);

With the error:

Error: Cannot find module './cfg'
    at Function.Module._resolveFilename (module.js:557:15)
    at Function.Module._load (module.js:484:25)
    at Module.require (module.js:606:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (C:\node\prj-node\prj-backend\test.js:3:14)
    at Module._compile (module.js:662:30)
    at Object.Module._extensions..js (module.js:673:10)
    at Module.load (module.js:575:32)
    at tryModuleLoad (module.js:515:12)
    at Function.Module._load (module.js:507:3)

EDIT: ( Background )

I am trying to get the npm package generic-rest-api going ( https://www.npmjs.com/package/generic-rest-api ) - to make it fast and secure to set up a REST Api to access data from sql server.

The usage is:

var genericRestApi = require('generic-rest-api'); app.use(genericRestApi(__dirname+'/models'));

Where the models directory contains the models I generated for sequelize. The package gives the same error.

Upvotes: 1

Views: 2853

Answers (1)

jfriend00
jfriend00

Reputation: 708156

The loading rules for require() when specifying a directory are all spelled out here. In summary:

LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text.  STOP
2. If X.js is a file, load X.js as JavaScript text.  STOP
3. If X.json is a file, parse X.json to a JavaScript Object.  STOP
4. If X.node is a file, load X.node as binary addon.  STOP

LOAD_INDEX(X)
1. If X/index.js is a file, load X/index.js as JavaScript text.  STOP
2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
3. If X/index.node is a file, load X/index.node as binary addon.  STOP

LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
   a. Parse X/package.json, and look for "main" field.
   b. let M = X + (json main field)
   c. LOAD_AS_FILE(M)
   d. LOAD_INDEX(M)
2. LOAD_INDEX(X)

So, your code:

var folder = require('./cfg');

will look for a variety of things, but if it doesn't find one of those specific options in that directory, it will fail.

In your case, it's looking for one of these files:

./cfg
./cfg.js
./cfg.json
./cfg.node
./cfg/index.js
./cfg/index.json
./cfg/index.node
./cfg/package.json

In all of these the . is relative to the where the current module that you're doing the require() in was loaded from.

But, since your file is ./cfg/config.js, you can see that none of these rules will attempt to look for that specific file.

Perhaps what you really need is:

var folder = require('./cfg/config.js');     

OK, now that you've edited your question to change the spelling, here's a new summary:

You say that this works:

var file = require('./cfg/config');
console.log(file);

to load config.js from the ./cfg directory. That means that the file must be ./cfg/config.js. That is as expected because per the rules above, it will try appending a .js to the path specified to see if that's a file.

You say that this doesn't work:

var folder = require('./cfg');
console.log(folder);

That is as expected because node.js has no automatic rule to look for config.js inside a directory unless there's a package.json whose main rule points at config.js.

Upvotes: 7

Related Questions