Intro
We're going to discuss here how to set up an express server but first we should talk about what that is. An express server is a JavaScript/Express file that resides in the root directory of the project's CWD. It is set up to process requests from a client terminal. This means we need a JavaScript file running on the server, (eg. index.js), with Express installed through the npm process.
Download all of the server project files: expressServer.zip.
You can access the "served" index.html file that we will create here @ localhost:3000, but remember, our server must be up and running to retrieve this file. We will discuss how to do this, here.
So how do actually create this Express server setup? Good question. The process has seven (7) basic steps:
- Create a working directory (CWD)
- Set up the directory structure
- Create an index/js file
- Initialize our npm structure (npm init)
- Install the Express package (npm i express)
- Write the Server application code in index.js
- Start the server (run nodemon index.js)
Directory Structure
So the first thing we need to do is to set up our working directory. This is going to start with a root directory. In this example, we'll call our root directory "project". We also need to create a public directory.
What is a "public" directory? Well, I'm glad you asked.
In a Node.js application, particularly when using Express, the public directory is a folder that contains static files such as HTML, CSS, JavaScript, images, and other assets that are served directly to the client without being processed by the server. This directory is typically configured to be accessible via the web server, allowing clients to request and receive these files directly.
So what happens once this is all configured properly, is that when a client terminal requests a webpage from the server, the server sends that page back to the client, along with all of the required static files that the page requires. So the server file is going to need to know where our "public" directory is, as it contains all of our static files.
This is all configured in the server setup and we'll get to that shortly, but for now we need to get our basic working directory set up (including a public directory). It will look something like this:
- project
public
css
images
scripts
index.html
index.js
This will take care of steps 1 thru 3 above.
- We created our CWD: "project"
- Our directory structure is set up, complete with the public directory and its appropriate sub-directories.
- (remember that this public directory is where all of our "static" files will be "served" from)
- (also, the sub-directories are optional as you may not need any of these, or you may have others that you do need)
- We created a index.html file which essentially becomes our website "home page", getting served from the server.
- (notice that this goes in the public directory as it is one of our necessary "static" files)
- We created our index.js file which will eventually become our server file. For now it is an empty file.
npm init
The next thing we need to do is run npm init to set up our package.json file. Once this is accomplished we will run [ npm -i packageName ] to install any npm packages that we need for our project. This will create our node_modules directory, and update our package.json file with the needed dependencies.
When we are finished, our directory structure will look something like this:
- project
node_modules
- (any npm installed packages will be here)
public
css
images
scripts
index.html
index.js
package-lock.json
package.json
and our package.json file will look something like this:
- {
- "name": "projectName",
- "version": "1.0.0",
- "description": "projectDescription",
- "keywords": [any, keywords],
- "author": "authorName",
- "license": "ISC",
- "main": "index.js",
- "type": "module", // either [commonjs] or [module]
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "dependencies": {
- any dependencies (from npm packages) are listed here
- }
- }
This will take care of steps 4 and 5 from above.
Most of this data is assigned during the npn init process, unless you specify the npm init -y option which skips all the questions asked during the init process and just accepts default values. You can always edit this file and enter the values manually.
Notice that main is pointing to index.js. This will be your "main" Js file for the project, (usually your "server" file). Also notice the type definition here. This defines how you are going to import packages into your Js file:
- commonjs: uses require for importing files - older method
- module: uses import for importing files - newer method
This must be defined here, or your imports will not work properly.
Server Code
This should get us to step 6, which is actually building the index.js server code. We're going to go ahead and document the code, then we will break it all down.
- JavaScript
- Server File
- import express from 'express';
-
- // dynamically build a path to the ROOT directory
- import { dirname } from 'path';
- import { fileURLToPath } from 'url';
- const __dirname = dirname(fileURLToPath(import.meta.url));
-
- const app = express();
- const port = process.env.PORT || 3000;
-
- app.use(express.static("public"));
-
- app.get( "/", ( req, res ) => res.sendFile( __dirname + "index.html") );
-
- app.listen( port, console.log(`Server running on port: ${port}` ) );
and let's break this all down, one line at a time:
- import express from "express"
- const app = express();
- const port = process.env.PORT || 3000;
- import { dirname } from 'path';
- import { fileURLToPath } from 'url';
- const __dirname = dirname(fileURLToPath(import.meta.url));
- app.use(express.static("public"));
- app.get( "/", ( req, res ) => res.sendFile( __dirname + "index.html") );
- app.listen( port, console.log(`Server running on port: ${port}` ) );
So this will complete our Step 6 in the process. All that is left is step 7: Start the server.
Starting & Stopping the Server
To actually "start" our server, we open up our Terminal of choice, navigate to our project's root directory, and enter nodemon index.js. Once the server is up and running we will see a console.log stating "The server is running and listening on port: 3000"
Now that our server is up and running, we can access the server output (our requested page), in our browser by entering http://localhost:3000 into the browser address bar.
Why are we're using "nodemon" instead of "node"?
Well, whether you use "node" or "nodemon" depends on where you are in the development process. While we are building and developing our project, we use "nodemon" because it stops and restarts our server when we make changes to the file structure. But if we are just "running" our server, we would probably just use "node".
And finally, now that our server is up and running, how do we shut it down? Once again, from the Terminal of choice,
and the index.js file that we are running, will terminate shutting down our server.
One last tidbit:
While we're talking about ports, if you open a Terminal, and enter the command:
- netstat -ano | findstr "LISTENING"
you will actually get a list of all of the ports that are open and "Listening" on your computer.