The MEAN Stack - Express

In this part of the MEAN series you will learn about Express. In the MEAN stack, Express has a unique place. Technically, all you do in Express... can be done directly in Node. But the code won’t look as elegant, and you will end up re-writing a lot of things. Express, in a way, is happily married to Node. They play very well together, and learning Express will make your job a lot easier going forward as a MEAN stack developer. With that said, let's hop on...

How to start an Express application?

  • This is easy. Open a terminal, create a folder expressdemo and navigate to it.
mkdir expressdemo && cd expressdemo
  • Initialize the application using npm init:
npm init
  • This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. You can either type a value in, or simply hit enter key to accept defaults. Notice that it writes to package.json and emits the text once done.
name: (express)
version: (1.0.0)
summary:
entry point: (index.js) server.js
test command:
git repository:
keywords:
author:  rahul soni
license: (ISC)
About to write to /Users/my_user_profile/Desktop/expressdemo/package.json:

{
  “name”: “expressdemo”,
  “version”: “1.0.0”,
  “summary”: “”,
  “main”: “server.js”,
  “scripts”: {
    “test”: “echo \”Error: no test specified\” && exit 1″
  },
  “author”: “ rahul soni”,
  “license”: “ISC”
}

Is this ok? (yes) yes
  • After you have initialised the app, go ahead and install Express. The switch –save will ensure that express is added as a dependency to the package.json file.
npm install express --save
  • Create a file called server.js, and paste the following text. The code is commented so that you understand what each section is doing.
//Load express and its dependencies
var express = require('express');

//Initialize express
var app = express();

//Default location (also called a Route). req = Request; res = Response
app.get('/', function (req, res) {
  res.send('Express says, hi there!!!');
});

//Open the port and listen to the requests! The port is 3000
var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Yesssss! I am up and listening for you at http://%s:%s', host, port);
});
  • From the terminal run the following, and browse to http://localhost:3000
node server
  • That’s it! You have express running, and it can handle a lot of tasks for you once it is configured.
  • If you are coming from .NET background, this may sound strange. You may be thinking about “so where does IIS fit in”? Well, Express is not a replacement for IIS or Apache. But it handles the request in quite a different way as you will see in the coming sections. It ties very well to Node applications, and has a pretty modular subsystem that can help you with a variety of tasks.

How to serve static files?

In the previous section, you found that you can have a separate route for your requests. Let’s take the routing concept a little further. Use the following code in the same server.js. You need to simply remove the code in server.js and paste the following:

//Load express and its dependencies
var express = require('express');

//Initialize express
var app = express();

//Default location (also called a Route). req = Request; res = Response
app.get('/', function (req, res) {
  res.send('Express says, hi there!!!');
});

//Route for /about
app.get('/about', function(req, res){
  res.send("About me!");
});

//Open the port and listen to the requests! The port is 3000
var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Yesssss! I am up and listening for you at http://%s:%s', host, port);
});
  • Once done, you can terminate the previous instance of Node (CTRL + C), and execute it again (node server). Now, if you hit http://localhost it will take you to default page, but http://localhost/about will take you to the About page.
  • This is quite straight forward. However, what if you have a bunch of files like js, css, html, pdf, etc?
  • This is where a little restructuring comes handy. Create a folder called public.
mkdir public && cd public
  • Create 2 or 3 files called 1.html, 2.html & 3.html, etc. And feed in some text in these files. The task is to send these static files to the client using a browser. This will require just one additional line of code like so:
//Load express and its dependencies
var express = require('express');

//Initialize express
var app = express();

//Load a module that would help in serving static files
app.use(express.static('public'));

//Default location (also called a Route). req = Request; res = Response
app.get('/', function (req, res) {
  res.send('Express says, hi there!!!');
});

//Route for /about
app.get('/about', function(req, res){
  res.send("About me!");
});

//Open the port and listen to the requests! The port is 3000
var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Yesssss! I am up and listening for you at http://%s:%s', host, port);
});
  • If you have more folders from where you would like to serve static from, you can add more app.use(express.static(‘vendor’)); functions to say so. Now, if you try to access the files using the URL, you will get the appropriate files back in your browser. If the browser can’t render the file, it will give you a download prompt and you will be allowed to save the file as usual.
http://localhost:3000/about
http://localhost:3000/1.html
http://localhost:3000/2.html
http://localhost:3000/3.html
  • Notice the fact that there is no mention of public here. Express simply searches relative to the folder. The benefit is that, you don’t have to explicitly add a subfolder. Express is smart enough to render everything inside of this path directly to the browser.

What will you do if the file names in different folders collide?

Let’s create a situation where the file path collides. Duplicate the public folder and call it vendor.

cp -r public vendor
  • So there are 2 folders (public & vendor) with identical files. Change the content of the files in vendor so that you can differentiate.
  • This is how my files look like:
$ cat public/* vendor/*
File 1
File 2
File 3
File 1 from Vendor
File 2 from Vendor
File 3 from vendor
  • Let’s add another static folder in the server.js file, like so:
//Load express and its dependencies
var express = require('express');

//Initialize express
var app = express();

//Load a module that would help in serving static files
app.use(express.static('vendor'));
app.use(express.static('public'));

//Default location (also called a Route). req = Request; res = Response
app.get('/', function (req, res) {
  res.send('Express says, hi there!!!');
});

//Route for /about
app.get('/about', function(req, res){
  res.send("About me!");
});

//Will this create conflict
app.get('/public', function (req,res){
  res.send("Public area");
})

//Open the port and listen to the requests! The port is 3000
var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Yesssss! I am up and listening for you at http://%s:%s', host, port);
});
  • Notice that vendor folder is included first and public later. If you try to access http://localhost:3000/1.html, you should see the content of vendor, and not from public. This happens because Express will deliver the file that it encounters first. If you change the order, you will see public folder’s content instead.

  • There is an easy fix to this, and it is called mounting the path virtually. Let’s see how to use it next. Notice how ‘/vendor’ and ‘/public’ is passed in app.use(...);

//Load express and its dependencies
var express = require('express');

//Initialize express
var app = express();

//Load a module that would help in serving static files
app.use('/vendor',express.static('vendor'));
app.use('/public',express.static('public'));

//Default location (also called a Route). req = Request; res = Response
app.get('/', function (req, res) {
  res.send('Express says, hi there!!!');
});

//Route for /about
app.get('/about', function(req, res){
  res.send("About me!");
});

//Will this create conflict
app.get('/public', function (req,res){
  res.send("Public area");
})

//Open the port and listen to the requests! The port is 3000
var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Yesssss! I am up and listening for you at http://%s:%s', host, port);
});
  • To access the files, you can now use the following and get expected results.
http://localhost:3000/vendor/1.html
http://localhost:3000/public/1.html
  • Express has a beautiful set of APIs which can be accessed here.
  • express.static is the only module that is built in. There are plenty of other modules available and that’s what makes Express fun!

Is there any known project structure that can help?

Yes, and it is extremely straightforward to use! For now, the work of expressdemo folder is done, and you can delete it. Let’s download a generator using npm.

sudo npm install express-generator -g

Assuming you have deleted expressdemo, you can try running these commands one by one:

express expressdemo && cd expressdemo //create the folder and navigate to it
npm install                           //Install dependencies (all of them are listed in package.json)
npm start                             //Start listening (more on this shortly)

That’s about it. Your application skeleton is ready, and if you try accessing http://localhost:3000 you should be able to see an output like so:

Express
Welcome to Express

What does npm start do anyway?

node server.js was straight forward, and you knew exactly what it is doing. However, npm start definitely looks weird to begin with. Basically, when you say npm start, it tells node to look for startup scripts. If it finds one, it executes it. The package.json created by the generator looks like this:

{
  "name": "expressdemo",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "express": "~4.13.1",
    "jade": "~1.11.0",
    "morgan": "~1.6.1",
    "serve-favicon": "~2.3.0"
  }
}

As can be seen, start points to the www script file that is inside of ./bin folder. This is where details like default PORT etc. is mentioned. You can tweak your information here, and access appropriately.

What next?

You have just started up with Express and learnt the basics. You can now look at the guide here to get further understanding of what it can do for you. I urge you to take a little time and read through it. You may be surprised to know how much you can achieve using Express.

Happy learning!

© 2023, Attosol Private Ltd. All Rights Reserved.