3

So I want to set up a basic node server to work with my clientside Angular application. My folder structure looks like this:

.tmp //Contains css stylesheet
bower //Obviously contains bower packages
public //Contains client code

This is what my index.html looks like (at least, the scripts/stylesheets)

 <!-- bower:css -->
  <link rel="stylesheet" href="bower/bootstrap/dist/css/bootstrap.css" />
  <!-- endbower -->
  <!-- inject:css -->
  <link rel="stylesheet" href="/.tmp/styles.css">
  <!-- endinject -->
<!-- bower:js -->
<script src="bower/jquery/dist/jquery.js"></script>
<script src="bower/angular/angular.js"></script>
<script src="bower/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower/angular-route/angular-route.js"></script>
<script src="bower/angular-resource/angular-resource.js"></script>
<!-- endbower -->

<!-- inject:js -->
<script src="/public/app/modules/sportStore.module.js"></script>
<script src="/public/app/controllers/checkout.controller.js"></script>
<script src="/public/app/controllers/productList.controller.js"></script>
<script src="/public/app/controllers/sportsStore.controller.js"></script>
<script src="/public/app/filters/customFilters.js"></script>
<script src="/public/app/components/cart/cart.js"></script>
<!-- endinject -->

And this is my middleware configuration in my server.js file:

app.use(logger()); //require('morgan')
app.use(express.static('./'));
app.use(express.static('./public/'));
app.use(express.static('./tmp/'));
app.use('/*', express.static('./public/index.html'));

What I understand this does is that: for every request:

  1. Log it
  2. See if you can find the file request under ./
  3. If it's not there, looks under ./public/
  4. If it's not there, look under ./tmp/
  5. If it's not there and the request contains something after the '/' serve index.html

How I'm going to handle client-side routing (with Angular's $routeProvider) is not clear to me yet, perhaps I won't even need to do that, I'm not sure if those requests will go to the server.

However doing all of this results in an infinite loop and I honestly have no idea why. I thought I understood middleware but obviously there's something wrong with my logic, or this would be working.

So basically my 2 questions are:

  1. Is what I summed up how express' middleware works?
  2. If it's not, perhaps you could give me a push in the right direction?

Don't just point me to express' docs, I've read them over like 5 times but I find that the documentation doesn't explain it clearly enough.

Robin-Hoodie
  • 4,886
  • 4
  • 30
  • 63

2 Answers2

2

A short answer is that middleware is everything you can plug for your requests' lifecycle. A good way to see how it works is to code a simple middleware, such as a very very basic logger middleware :

var logMiddleware = function(req, res, next) {
    // We do some logging
    console.log(req.method+" "+req.url);

    // Because this is a **middle**ware, we can stop the request here
    // using the res object, or call next() and it will continue it's 
    // lifecycle.
    next();
}


app.use(logMiddleware);

The order in which you register your middlewares (using app.use) does matter, it is a chain as you said in your original question.

Edit: Regarding Angular, you can have a look at this blog post and see how the routes are setup server-side. It's a bit old, but this part has not changed in express.

Tristan Foureur
  • 1,647
  • 10
  • 23
  • I'll take a look at that article, thanks for your answer! I'll also try out that piece of code to better understand it – Robin-Hoodie Apr 11 '15 at 12:30
1

Close. Your static routes look OK. The biggest issue with this is the 'path' - not the middleware. I think what you want is:

app.use(function(req, res) {
   res.redirect('/public/index.html'); // note: redirecting to root, not ./public
});

However it may be better to not serve up everything statically! You could do the following:

app.use('/public', express.static(__dirname + '/public');
app.use('/bower', express.static(__dirname + '/bower'));
app.use('/.tmp', express.static(__dirname + '/.tmp'));

app.use(function(req, res) {
   res.redirect('/public/index.html');
});

That will avoid any issues with files of the same name in different folders etc, and hides the code you don't want to give people access to...

olan
  • 3,568
  • 5
  • 24
  • 30