Nic Meiring
Nic Meiring

Reputation: 882

Using express to set up a basic server

I have a node.js application and I am stuck getting an error message when I try to load the homepage. I will do my best at laying out my architecture below. It goes index.js --> server.js --> router.js --> requestHandlers.js

I am using a combination of express (www.expressjs.com) and nodebeginner.org. Sorry for the long question.. just wanted to get as much information down as possible.

index.js (creates handle object that contains pathname/requesthandler information, calls function to start server) I start with router.route here and pass it along each step

var server = require("./server");
var router = require('./router');
var requestHandlers = require('./requestHandlers');

// Routes

var handle = {}
handle['/'] = requestHandlers.home;

server.start(router.route, handle)

server.js (starts the server, THIS IS WHERE I WANT TO CONFIGURE THE SERVER, gets a the pathname from the URL, and passes it on to the route module)

var http = require("http");
var url = require('url');
var express = require('express');

function start (route, handle) {
    var onRequest = function(request, res) {
        var pathname = url.parse(request.url).pathname;
        console.log("request for " + pathname + " recieved.");
        route(handle, pathname, res);
    }

    var app = express.createServer(onRequest).listen(8888);
    if (app.configure) {
        console.log('app exists'); //logging correctly
    }
    // Configuration
     app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

    console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); //logs correct with 8888 and development
}

exports.start = start;

router.js (the function route passed from index --> server which calls the route function in router.js, calls the requestHandler that matches the pathname in handle object)

function route (handle, pathname, res) {

    console.log("About to route a request for" + pathname); //About to route a request for/stylesheets/style.css SEE BELOW******* this is the error

if (typeof handle[pathname] === 'function') {
        handle[pathname] (res);
    }
    else {
        console.log('no request handler found for' + pathname);
    }
}

exports.route = route;

requestHandler.js (interacts with the res/req objects, functions are mapped to certain pathnames, only called when those pathnames are requested thanks to the router)

var home = function(res){
  res.render('index', { title: 'WWYB?' });
  console.log('homepage rendered'); //correctly logs for pathname = '/'
  //click();
};

exports.home = home;

***when i go to request localhost:8888 it tries to make a bunch of requests. first it requests "/" correctly but then keeps going through logging everything saying "About to route a request for/stylesheets/style.css" Eventually the page loads with no css. The pathname as indicated in my layout.jade file is exactly that '/stylesheets/style.css'.

Why is the pathname ever evaluating to /stylesheets/style.css? I think node is doing something in the background and I dont fully understand it.

Let me know if you need more info. Thanks!

Upvotes: 1

Views: 2718

Answers (2)

kevin
kevin

Reputation: 1572

Like @TJHolowaychuk commented you really should check the manual, and follow a bunch of tutorials. Anyway, I'll try to help you a bit.

The is a very basic explanation. Express allows you to use sub applications, so you can have different part of you application in different files. It has it's own router too. If you need to do something with the request and/or the response before the route is processed, you can create a middleware. If you want you configurations in a different module, then return a function in it.

So an example of server.js :

var  $express = require('express'),
          app = module.exports = $express.createServer(),
       subapp = require('./subapp'),
    configure = require('./configure');

// Each of our own configure returns a function that will be
// called by app.configure
app.configure(configure.all(app));
app.configure('development', configure.devel(app));
app.configure('production', configure.prod(app));

// Use our sub application
app.use(subapp);

// Now listen
app.listen(3030)

subapp.js :

var $express = require('express'),
    subapp = module.exports = $express.createServer();

// Add a handler for GET / to our sub-application
subapp.get('/', function (req, res) {
   res.end('Hello world!');
});

Finally configure.js :

var $express = require('express');

exports.all = function (app) {
   return function () {
      // Global configurations

      app.use($express.bodyParser());
      app.use($express.methodOverride());
      app.set('views', __dirname + '/views');
      app.set('view engine', 'jade');
      app.use($express.static(__dirname + '/public'));
      //...

      // If you want to do something with/on the request/response
      // you can create a middleware
      app.use(function (req, res, next) {
         console.log('caught request %s %s', req.method, req.path);

         // Don't forget the callback
         next();
      });
   };
};

exports.devel = function (app) {
   return function () {
      // Development configurations
   };
};

//...

Go to localhost:3030 with your favorite browser, it displays "Hello world!", this is our request handler. If you look at the terminal, you'll see "caught request GET /", this is our middleware.

Your stylesheets, client-side javascripts, etc. should be in /public. app.use(express.static(__dirname + '/public')) will serve these.

Let's say you have /public/stylesheets/all.css, then in your jade template you can include it like this link(rel='stylesheet', href='/public/stylesheets/all.css')

Now, you'll have to experiment and learn more about node and express before even thinking to deploy something to production, these websites may help you:

Hope this tiny-micro-tut helps you.

Upvotes: 5

TJ Holowaychuk
TJ Holowaychuk

Reputation: 261

woah this is pretty confusing, you might want to start with the app express(1) can generate for you

Upvotes: 4

Related Questions