Chapter 2 ■ hello World
23
■Note While installing, you can give a specific version to install using the suffix
@<version>, for example, npm install [email protected]. When not specified, it installs the latest version. If something is not working as described in this book, it may be due to a difference in version that you have installed vis-à-vis the version I used when writing the book. In such cases, you can try installing the same version as I have used for this book. For a list of the version of all packages, please refer to the final package.json file in the Github repository that contains the source code for this book.
Chapter 2 ■ hello World
npm is extremely powerful, and its options are vast. For the moment, we will concern ourselves only with the installation of packages and a few other useful things. The location of the installed files under the project directory is a conscious choice that the makers of npm made. This has the following effect:
1. All installations are local to the project directory. This means that another project can use a different version of any of the installed packages. This may at first seem unnecessary and feel like a lot of duplication. But you will really appreciate this feature of npm when you start multiple Node.js projects and don’t want to deal with a package upgrade that you don’t need. Further, you will notice that the entire Express package, including all dependencies, is just 1.8Mb. With such tiny sizes, you needn’t be worried about excessive disk usage either.
2. A package’s dependencies are also isolated within the package. Thus, you could, by all means, have two packages depending on different versions of a common package, and they would each have their own copy and therefore work flawlessly.
3. You don’t need administrator (superuser) rights to install a package.
There is, of course, an option to install packages globally, and sometimes it is useful to do this. One use case is when a command-line utility is packaged as an npm package.
You typically want the command line to be available regardless of the current directory, and in this case, you would choose a global install. In such cases, the –g option of npm install can be used, but you may need admin or root access to do this depending on your OS and type of installation.
Express
Express, if you remember the introduction in the previous chapter, is the best way to run an HTTP server in the Node.js environment. For starters, we’ll use Express to serve only static files. This is so that you get used to what Express does, without getting into a lot of server-side coding.
To start using Express, you need to import the module, and use the top level function that the module exports, in order to instantiate an application. You can create multiple applications, which listen on different ports, but we won’t do that. We’ll instantiate just one application. The listen() method of the application takes in a port number and starts the server, which then waits eternally for requests. But before you start listening on a port, you need to set up the application to tell it how to respond to certain requests.
Express is a framework that does minimal work by itself; instead, it gets most of the job done by functions called middleware. A middleware is a function that takes in an HTTP request and response object, plus the next middleware function in the chain. The function can look at and modify the request and response objects, respond to requests, or decide to continue with middleware chain by calling the next function.
Chapter 2 ■ hello World
25 The express.static generator function generates one such middleware function.
This middleware responds to a request by trying to match the request URL with a file under a directory specified by the parameter to the generator function. If a file exists, it returns the contents of the file as the response; if not, it chains to the next middleware function. The middleware is mounted on the application using the application’s use() method.
Let’s put all this together in a file called server.js in the root directory of the project.
Listing 2-2 shows the code that is needed to achieve a simple static server.
Listing 2-2. server.js: Express Server const express = require('express');
const app = express();
app.use(express.static('static'));
app.listen(3000, function () {
console.log('App started on port 3000');
});
Let’s create a directory named static under the project directory and move index.html (which we created in the previous section) into this directory. Now we can start the web server and serve index.html. To start the web-server, do this on the console:
$ npm start
You should see a message saying the application has started on port 3000. Open up your browser and type http://localhost:3000 in the URL bar. You should see the same Hello World page.
Let’s examine the server code and understand its contents in detail.
...
const express = require('express');
...
require is a JavaScript keyword specific to Node.js, and it is used to import other modules. In the above line, we loaded up the module called express and saved the top-level thing that the module exports, in the constant named express. Node.js allows the thing to be a function, an object, or whatever can fit into a variable. The type and form of what the module exports is really up to the module, and the documentation of the module will tell you how to use it. In the case of Express, the module exports a function that can be used to instantiate an application.
Note that we are using const and not var. This is because we are using the ECMAScript 2015 (ES2015) specification of JavaScript. You may also see references to ECMAScript 6th Edition (ES6), which is just an older name for ES2015. ECMAScript 6th edition was renamed to ECMAScript 2015 recently.
Chapter 2 ■ hello World
Node.js supports ES2015 to a large extent, so we will be using the ES2015 features and style of programming. We’ll be using ES2015 for the client-side code, so we might as well use the same on the server, so as to have a consistent style throughout.
...
const app = express();
app.use(express.static('static'));
...
This instantiates the application and then mounts a middleware. The middleware generator takes the parameter static to indicate that this is the directory where all the static files reside. Remember that we moved index.html into this directory.
The express.static generated middleware function is also smart enough to translate a request to “/” (the root of the website) and respond by looking for index.html in the directory. This is similar to what other static web servers such as Apache would have done. You could also have used http://localhost:3000/index.html to access the application and seen the familiar Hello World.