10

As a learning exercise, I am attempting to build a router in Node.js, which is meant to be reusable.

The file structure for my router looks like this:

/myProject
    app.js
    /routes
        index.js
        about.js
    /modules
        /router
            router.js

In app.js, I create a router object, and pass it the path to my routes folder:

var Router = require('./modules/router/router');
var router = new Router('./routes');

Within the constructor of the router object, I load filenames into an array from the path passed to the object, and attempt to add them to an object as a module:

var fs = require('fs');
var routes = {}
var routesFolder;

function Router(routesPath){
    this.routesFolder = routesPath;
    fs.readdir(this.routesFolder, this.loadRoutes);
}

Router.prototype.loadRoutes(err, files){
    for (var i=0;i<files.length;i++){
        var c = files[i].split('.');
        if(c[1] === 'js'){
            try{
                var t = require(routesFolder + '/' + c[0]);
                routes['/' + c[0]] = t[c[0]];
            }
            catch(err){
                console.log('Error parsing file: ' + files[i];
                console.log(err);
            }
        }
    }
}

My index.js and about.js files look like this:

exports.index = function(req, res){
    // Some code here
}

I run node app.js, and I pass the router object ./routes as the route's path. The file names load just fine, but my console output is:

Error parsing: index.js
{ [Error: Cannot find module './routes/index'] code: 'MODULE_NOT_FOUND' }
Error parsing: about.js
{ [Error: Cannot find module './routes/about'] code: 'MODULE_NOT_FOUND' }

I have attempted to alter my routes files in a few different ways:

module.exports = function(){...}
module.exports.index = function(){...}

But this has no effect. From what I understand about node and require, this should work. I'm a bit of a novice, so please forgive me if the issue here is something silly.

4

1 回答 1

13

You should use an absolute path to your routes folder:

var path = require("path");
var Router = require('./modules/router/router');
var router = new Router(path.join(__dirname,'routes'));

I think what is happening is that fs.readdir is using the process.cwd which is the directory of app.js but require() always uses the location of the current script when resolving relative paths and is thus looking for files like /myProject/modules/router/routes/index.js.

于 2013-10-09T16:14:41.270 回答