Getting MEAN: Serving Static Files

We will need a web server to serve static files. The LAMP stack is based upon the Apache Web Server. As this server will develop into a true “back-end” for our REST API, we might as well use the same server to serve static files – at least during the development phase of this project.

The backend server of choice in Node.js is called Express.

Git branch

First step is to create a branch for this particular step of our development. In the previous section we cloned a mostly empty Git repository (almost – it did contain a README.md file) and initialized our project. We now create a new branch which we will call static:

lth@ncpws04:~/src/notes$ git branch static 
lth@ncpws04:~/src/notes$ git checkout static
Switched to branch 'static'
lth@ncpws04:~/src/notes$

Installing Express

We use npm to handle our various dependencies. Since we have already created the package.json for our project, we can now install express.js:

lth@ncpws04:~/src/notes$ npm install express --save
npm notice created a lockfile as package-lock.json. You should commit this file.
+ express@4.16.2
added 48 packages in 11.311s
lth@ncpws04:~/src/notes$

Dependencies installed by npm will end up in a directory called “node_modules”. The result of the npm install we just ran is that node_modules now contains:

lth@ncpws04:~/src/notes$ ls -l node_modules/
total 188
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 accepts
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 array-flatten
drwxr-xr-x 3 lth lth 4096 Oct 19 14:45 body-parser
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 bytes
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 content-disposition
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 content-type
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 cookie
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 cookie-signature
drwxr-xr-x 3 lth lth 4096 Oct 19 14:45 debug
drwxr-xr-x 3 lth lth 4096 Oct 19 14:45 depd
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 destroy
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 ee-first
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 encodeurl
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 escape-html
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 etag
drwxr-xr-x 3 lth lth 4096 Oct 19 14:45 express
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 finalhandler
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 forwarded
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 fresh
drwxr-xr-x 3 lth lth 4096 Oct 19 14:45 http-errors
drwxr-xr-x 4 lth lth 4096 Oct 19 14:45 iconv-lite
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 inherits
drwxr-xr-x 5 lth lth 4096 Oct 19 14:45 ipaddr.js
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 media-typer
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 merge-descriptors
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 methods
drwxr-xr-x 3 lth lth 4096 Oct 19 14:45 mime
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 mime-db
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 mime-types
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 ms
drwxr-xr-x 3 lth lth 4096 Oct 19 14:45 negotiator
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 on-finished
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 parseurl
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 path-to-regexp
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 proxy-addr
drwxr-xr-x 5 lth lth 4096 Oct 19 14:45 qs
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 range-parser
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 raw-body
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 safe-buffer
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 send
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 serve-static
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 setprototypeof
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 statuses
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 type-is
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 unpipe
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 utils-merge
drwxr-xr-x 2 lth lth 4096 Oct 19 14:45 vary
lth@ncpws04:~/src/notes$

That might look at bit surprising. We only wanted express, so why on earth does the node_modules contain that many modules. The simple answer is dependencies. When we installed express with npm and the –save option, we essentially told npm that our project depended on express. The content of our package.json is now:

{
  "name": "notes",
  "version": "0.0.1",
  "description": "Notes Application",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/lbthomsen/notes.git"
  },
  "keywords": [
    "notes"
  ],
  "author": "Lars Boegild Thomsen <lbthomsen@gmail.com>",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/lbthomsen/notes/issues"
  },
  "homepage": "https://github.com/lbthomsen/notes#readme",
  "dependencies": {
    "express": "^4.16.2"
  }
}

Similarly, express have dependencies, and those are the ones you now see in the node_modules folder.

Since the node_modules can be recreated at any time, it does not make sense to include it in our git repository. So let’s create a .gitignore file with the following content:

lth@ncpws04:~/src/notes$ cat .gitignore 
node_modules/

A single line.

Finally add the .gitignore to the repository itself and commit the changes.

lth@ncpws04:~/src/notes$ git add .gitignore 
lth@ncpws04:~/src/notes$ git commit -a -m "Added .gitignore"
[static 88169fa] Added .gitignore
 2 files changed, 5 insertions(+), 1 deletion(-)
 create mode 100644 .gitignore

Creating our initial index.html

Before creating the express server we need a file to serve 🙂 We will create a directory called “src” and an initial index.html in that directory:

lth@ncpws04:~/src/notes$ mkdir src
lth@ncpws04:~/src/notes$ vi src/index.html

The index.html should contain the following:

<!DOCTYPE html>
<html>
    <head>
        <title>Notes App</title>
    </head>
    <body>
        <p>
            Hello World!
        </p>
    </body>
</html>
<!--+
    | vim: ts=4 et nowrap autoindent
    +-->

Let’s not forget to add this directory (with it’s contents) to our git repository and commit our changes:

lth@ncpws04:~/src/notes$ git add src
lth@ncpws04:~/src/notes$ git commit -a -m "Added src/index.html"
[static ccd84b5] Added src/index.html
 1 file changed, 14 insertions(+)
 create mode 100644 src/index.html

We can now move on to our next step – which is to serve this file (and other files in the src folder).

Making express serve static files

Using our favorite text editor (which should be vim), create a file called server.js

The first step will be to use the express module that we earlier installed with npm:

var express = require("express");

We now instruct express to start a server process:

var app = express();

We instruct the server process to serve static files from our src directory:

app.use(express.static("./src"));

And finally, instruct the server process to listen to network connections on port 8080:

app.listen(8080);

That is basically it. The complete server.js will look like:

/* 
 * Notes Server
 */

var express = require("express");
var app = express();

app.use(express.static("./src"));

app.listen(8080)

/*
 * vim: ts=4 et nowrap autoindent
 */

Let’s try to run the server and check the page in a browser. First start the server:

lth@ncpws04:~/src/notes$ node server

And try to access the URL: http://localhost:8080 in a browser. The result is:

Commit changes to git

Finally add the server.js to git, commit and push the changes upstream:

lth@ncpws04:~/src/notes$ git add server.js 
lth@ncpws04:~/src/notes$ git commit -a -m "Added server.js - serving static files"
[static a92db8a] Added server.js - serving static files
 1 file changed, 14 insertions(+)
 create mode 100644 server.js
lth@ncpws04:~/src/notes$ git push --set-upstream origin static
Counting objects: 11, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (11/11), 1.18 KiB | 0 bytes/s, done.
Total 11 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 1 local object.
To github.com:lbthomsen/notes.git
 * [new branch]      static -> static
Branch static set up to track remote branch static from origin.

1 thought on “Getting MEAN: Serving Static Files

Leave a Comment