package.json
fileThis is Part 2 of the lab exercise for Node.js. In Part 1 you downloaded and installed Node.js and practiced running JavaScript commands in the Node.js REPL. In Part 2, you will create a JavaScript file in Sublime/VSCODE/ATOM in which you will code a server using Node.js.
Use the Terminal for navigating around the file system and creating new folders and files. Refer to the lesson on Shell Commands if you need guidance on using the Terminal.
When you get to the steps below that ask you to initialize a git repo and track files using git, refer to the lesson on Git and Version Control if you need guidance.
Navigate to the techtonica-labs
folder located in your Desktop. Create a new folder called getting-started-with-node
within the techtonica-labs
folder. Navigate to getting-started-with-node
. Initialize getting-started-with-node
as a git repository.
If you have questions, do not disturb other pairs until you have spent 15-20 minutes troubleshooting within your own pair. Post a message on the #help channel in Slack if you and your pair partner are still stuck after 15-20 minutes. Be sure to format your question using the template we practiced in the Asking Good Questions lesson.
There is no starter code for this lab exercise.
This video covers all the material in this lab exercise. Please refer to it if you get stuck.
First step
From your Terminal, create a new file called app.js
in your getting-started-with-node
folder. Open app.js
using the Sublime shortcut in your Terminal. Add a print statement to your file, such as this:
console.log("I'm learning to use Node.js!");
Save the file.
Second step
Return to your Terminal. Make sure your current working directory is your getting-started-with-node
folder. Run the app.js
file by entering this command in the Terminal:
node app.js
What happened?
Third step
Open the app.js
file again. Replace the print statement with a function that prints something different to the console. Save the file, then run it again with node app.js
. What happened?
If nothing printed to the Terminal, you are missing something in your app.js
file.
package.json
fileFirst step
Every node project needs to have a package.json
file because this file holds metadata about the project, such as who created it, what version it is, and what the dependencies are.
The node package manager (npm) guides us through creating a package.json
file. From your getting-started-with-node
folder run this command:
npm init
You will see a succession of prompts appear in the Terminal. Type in your responses where appropriate, though for our purposes it’s OK to just go with the defaults for now by pressing < ENTER > for each prompt that does not need to be customized.
Once successful, you’ll see a JSON object printed to your Terminal.
Another way to create a package.json
file is using npm init -y
The -y flag when passed to npm commands tells the generator to use the defaults instead of asking questions.
Second step
While in your getting-started-with-node
folder, running the ls
command should reveal that a new package.json
file has been added to the folder. Open package.json
in your text editor and see what’s inside the file. It should be the same as the JSON that was printed to your Terminal in Step 1.
First step
Open app.js
and delete the function you wrote in the previous step. In its place, we need to add the code given below. Do not copy and paste this code into your file.
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader = ('Content-type', 'text/plain');
res.end('Hello World!');
});
Before reading the line-by-line descriptions that follow, discuss with your pair partner what you think each line of code is doing in the above snippet. Then, read the descriptions below.
So far, you are used to creating a variable with the
var
keyword. The keywordconst
(short for “constant”) is a way of creating a variable name that can never be reassigned to another value within your program. When you create a variable withconst
, the value that is associated with that variable name is constant throughout the entire program. If you usedvar
instead when creating a server, you could mistakenly reassignport
orhostname
to other values and accidentally crash your server. This StackOverflow thread has more details. This response in particular is sufficient for our purposes.
What follows is a description of what each line of code is doing. Try to explain the code yourself before reading on.
const http = require('http');
imports the HTTP module and binds it to a variable called http
. The HTTP module comes with Node.js so we don’t have to download it separately; we can just import it directly.
const hostname = '127.0.0.1';
binds a string containing the web address of our local server to a variable called hostname
. Using the web address of our local server lets us serve our webpage to our local machine rather than to a URL. Remember, regardless of which computer you are on, 127.0.0.1
is always localhost
.
const port = 3000;
binds the port number we want to listen in on to a variable called port
. When a server “listens” to a port it is listening for requests and responses sent to/from that port.
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader = ('Content-type', 'text/plain');
res.end('Hello World!');
});
calls the createServer
method on our http
object. The result is a server instance, which we bind to a variable called server
. We are setting the response’s status code to be 200, which means ‘OK’. We are setting the response’s header to contain plain text. And res.end()
concludes the server’s response after rendering ‘Hello World!’.
Now that you understand what the code is doing, type the code into your app.js
file by hand. Save the file before continuing.
Second step
There’s a little more code we need to write before we can run app.js
in Node: we need to tell the server to listen to the port we’ve specified and to send responses to the hostname
we’ve specified. To do this, we call the .listen()
method on our server
object, passing in port
, hostname
and a callback function as arguments. The body of this callback function contains a print statement that will print to the Terminal while the server is running. Type the following code onto the end your app.js
file by hand.
Save the changes you made to app.js
.
From the getting-started-with-node
directory in your Terminal, run the command node app.js
. What happens?
You should see the message you specified in your console.log() command appear in your Terminal — that means your server is running! Congratulations!
There’s one last thing we need to check. Remember that our server instance is supposed to send ‘Hello World!’ to the client making the request? Open a new tab in Chrome and navigate to http://127.0.0.1:3000. What do you see? Now, open another tab and navigate to http://localhost:3000. What do you see now?
In the Terminal, press < CONTROL > + C to shut down the server. We’ll boot it up again later.
First step
What we’ve done so far in this lab exercise has allowed you to take a huge leap forward in what is now possible for you to build. But we’re not quite there yet. Web servers serve web pages, so let’s learn how to do that next.
First, create a new file called index.html
in your getting-started-with-node
directory. Open it in Sublime. Copy and paste this code snippet into index.html
:
<!DOCTYPE html>
<head>
<title>First Node App!</title>
</head>
<body>
<h1>Welcome to my first Node app!</h1>
<p>Node is awesome.</p>
</body>
</html>
Save the file.
Second Step We need to tweak the app.js
file a little because right now it sends ‘Hello World’ as a response, and we want it to send the entire index.html
file as a response instead.
The first thing we need to do is import the filesystem module, called fs
. We’ll do this in exactly the same way we imported the http
module. Add this line of code just under the line that imports the http
module:
const fs = require('fs');
Next, we need to tell our server that index.html
exists. We can do that with the .readFile()
method from the fs
module, which takes the filename (index.html
) and a callback function as arguments. The callback function itself takes an error message and some HTML code as arguments. Type (don’t copy and paste) this code after the line where you’ve created the port
constant variable:
Within this function we first need to handle any error(s) that might appear. Then, we can rendex index.html
. We can add a few short lines of code inside the callback function in order to process any errors:
We can copy and paste all the rest of our code below the if statement, keeping it inside of the fs.readfile()
call. Putting the rest of our code here means that if there are no errors, the index.html
file will be rendered to the web page. But if errors are present, an error message will show and the index.html
file will not be rendered. Make your app.js
file look like this:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
fs.readFile('index.html', (err, html) => {
if (err) {
throw err;
}
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader = ('Content-type', 'text/plain');
res.end('Hello World!');
});
server.listen(port, hostname, () => {
console.log('Server running on port ' + port + '...');
});
});
Save the file.
Third Step
There are just 3 lines of code we need to edit now in order to have index.html
served to localhost
!
First, remove the string inside the res.end()
method call so all that remains is:
res.end();
Second, add a line of code above res.end()
that looks like the code below. This extra line will send inside the response the HTML code received from index.html
.
res.write(html);
Finally, in the res.setHeader()
method call, change text/plain
to text/html
.
Save the file.
Re-start the server in the Terminal by running node app.js
from within the getting-started-with-node
directory. You should see “Server running on port 3000…” printed to the Terminal.
Next, open a new tab in Chrome and navigate to http://localhost:3000. You should see the index.html
in all its rendered glory! Also note that the text that appears in the tab’s title matches what you specified inside the <title>
tags in index.html
.