I’ve spent a fair while practicing making pages using html and css, but when it came to stuff like serving them or running anything through the terminal, it just seemed like way too big a thing to learn. I couldn’t wrap my head around any of the concepts I was reading about. All this talk of requests, responses, get vs post, etc. It felt like I was back when I first started learning, where there were a bunch of made up words everyone was talking with and I had understanding of neither the words themselves nor the context in which they were being used.
It’s taken me a while but now I can at least understand enough to serve some files on localhost. This is a step up from where I was a few weeks ago. While I was showing a coworker, he informed me gently that I should have started with Sinatra for Ruby since it’s more of a plug-and-go type deal, but there we go. This post is an article explaining how to set up a nodejs project, install express and serve your files (html, css, js) on localhost:<port number of your choice>. It doesn’t go into making it available for others to see, ie through sites like Heroku. As I progress, I hope to talk about that topic at a later date.
I decided to learn to do this with ExpressJS since it seems to be the most common web app framework for nodejs projects, and I am trying to stay on the languages I can already use before straying into others such as Go or Ruby. I’ll be learning about Go in the future though, since that’s the language most of the services at my workplace are written in.
Setting up the project
The first thing you need to do when starting a new project is, well, make a new project. If you have many projects you want to make, it’s a good idea to make a folder to keep them in. Inside that, you can make a new folder for this project. In terminal, simply type:
This creates a folder in your current location by that name. It doesn’t put you into that folder though, so you need to change your current directory to your new project folder so that you are working inside it. Otherwise any files and packages you make or install will be in the wrong place. Change directory to the correct one using the command:
After you’ve made your project folder and changed directory to it as above, you should run the command:
This will ask you questions about your project in order to build your package.json file. This is where you manage your packages, ie information about your project and what dependencies it has, etc.
This is what a package.json file looks like:
You can skip over some of the questions by pressing enter in the terminal, as I did in the above example. If you know the correct syntax then you can create and write this file yourself without running a command from terminal. The important parts are the name and the entry point (called “main” above). That says the name of the file where you keep instructions about what your app actually does. You can name it anything, but it is usually called something like app.js or index.js.
The next thing we want to do is install express. NPM makes this really easy – just go back to terminal and use the command:
npm install express –save
This adds the express dependency to your package.json file, which again you can do manually without the terminal command if you want to. It’s good to use the terminal when you can though, since it’s something everyone has to get used to when they start development. It also takes away the risk that you will write something wrong and not know why it’s not working. The package.json file now looks like this:
Next up you should run the command:
This installs node modules, which are kind of like built-in libraries that let you use keywords without having to define them yourself. You need these to do all of the things.
For example, as a simple trial you can put a console.log() in there:
When you run the app from terminal, your text will appear in the terminal like so:
Starting the server
Ok so now you have the project and file structure set up, it’s time to actually put something up on a page. This is what you need express for.
I’ve made a few little ‘webpages’, which I would open by dragging the index.html file into my browser. What I wanted was to be able to run a command in terminal which would open my app on a localhost:<port number> page.
To do this, you need to look at the entry file (app.js) and write some code. I won’t pretend to understand exactly what each line does and why it works the way it does, but I think I get the gist of it which is fine for now.
These lines go at the top. This is where you tell the computer which modules/packages you will be using, which in turn allows you to use functions and keywords associated with them. For example, you can’t use any functions associated with express unless you’ve told it that it needs to find the express module that defines what they are and what they do.
The way I understand it is: if you asked a child to get you an apple, they would first need to know what it means to ‘get’ something. Otherwise they wouldn’t know what to do with the apple. So you have to teach the child what getting is first, but you don’t want to do that yourself so you just send the child to school where there are teachers to tell it how to do stuff. These lines in the code are like telling the child which class in school to remember so they know how to ‘get’ an apple for you. This is why the node modules are important – they’re the school that tells stuff to your kid so you don’t have to do it yourself.
The next line simply initialises the app, and the last one listens on the port 3000 and then does whatever is inside the curly brackets when the server starts. I moved my console.log line into here for demonstration. This does the same thing as before, by logging your text in the terminal after you run the app:
You might notice one difference from the last time. When there was only the console.log line in the file, running the app would run that command and then finish so that you could do other things in the terminal afterwards. This time, you get a white rectangle instead of space to type. That’s because your server is now up and running. While it’s running, you will need to open a new tab in your terminal if you want to do other things.
The text you add there would usually say something like “Server started on port 3000” though, as you want it to be useful and intuitive.
Great, you might think. This means you’re serving on the port 3000 so you can type “localhost:3000” in your browser and get whatever you like. If you do that though, you get an error:
Without knowledge, it seems like it’s not telling you what it can’t GET. Can’t get what? What are you even trying to get?? It’s trying to get ‘/’. That’s because this is the homepage. If you go to a website such as https://undevelopedbruce.com, you go to the main page. If you wanted to go to the about page, you’d add “/about-me” onto the end, or “/contact” for the contact page. There isn’t a “/homepage” because “/” on its own is the main page.
The reason you get the above error is that there’s no route set up for this page. The computer is trying to open “localhost:3000/” but it doesn’t know the path to the contents because we haven’t defined it.
We do that by adding the following text after the line that initialises our app (var app = express();)
The ‘get’ keyword is for handling get requests. When you type localhost:3000, your browser makes a get request to the server, asking for the contents of the page. After that we have ‘/’, which says which page it’s looking for. If you changed the above to “/bruceisawesome” then you’d have to go to “localhost:3000/bruceisawesome” to see the text.
The words req and res are short for request and response, and these are the parameters of the function you’re writing. ie, we get a request and send a response.
Inside the curly brackets of the function is where we define the response, in this case “when a request is sent for “localhost:3000/”, respond by sending this string”.
In order to see the update, you need to stop your server in terminal and restart it. You can do this by pressing ctrl+c then running the node app.js command again.
As an aside, you could also install nodemon globally on your system, then run the command nodemon app instead of node app. This watches out for changes to your code and automatically restarts the server when you save changes to associated files.
Now refresh the browser page and you should see whatever text you added!
Hosting your files
Ok so we’ve managed to get some text to appear in the browser, but it’s not the 1980s and that does not constitute a webpage. We want to put up a html file with the contents, maybe with some css for styling as well. You can’t just drop the html contents into your app.js file though. You want nice clean, separated code that you can manage and update. You need the entry file to pick up the html and css files you want, and serve them for you.
Doing that is simple and you can find the documentation here for serving static files using express.
The above line of code tells the computer executing it where to find the directory where you put your files. “__dirname” is a way of pointing to the directory you’re in, without having to put the whole path in. So instead of typing usr/projects/thisproject/folder, so long as the app.js file is in thisproject, it will find ‘folder’ in ‘thisproject’ for you. Alternatively, if you want to point it to the directory where you’re running node from, ie your working directory in terminal, then you can replace “__dirname” with “./”
Next up, you need to make that folder exist. In the above example, the folder is named public, so that’s what you need to make. There is no specific word you must use, but some like that one are common.
Here you can see I created a folder called public, and made an index.html file inside that. If you do the same, make something really simple that just has some text in then go back to localhost:3000, you should get whatever you placed in that file:
I don’t yet know anything about hosting elsewhere so that people on other machines can access your page, but a quick search found this page, which lists a few sites or services you can use to host your nodejs project if you want to make it available for the rest of the world to see.