Skip to content

Node.js

benedictbrown edited this page Sep 18, 2018 · 1 revision

Node.js

Google V8 Javascript JIT compiler paved the way for real web applications by making Javascript fast enough for large projects. It's only a short hop from, "Javascript executes fast enough for real client-side web application development," to, "Javascript executes fast enough to use on the server." Using Javascript for all parts of the web application, rather than using something else on the server (Python, Java, PHP, Perl, and C++ are all common options) is certainly enticing. It makes it possible to share code between the client- and server- sides of the application, and means you only have to deal with one language and development environment rather than two. On the other hand, Javascript is single-threaded by design, making it very hard for the server to handle multiple connections simultaneously, and it lacks basic functionality for interacting with the operating system and disk since those things aren't required within the browser. Until quite recently, there was also no reasonable way to break a Javascript program into multiple files.

Node.js, first released in 2009 and built on top of the V8 engine, is a server-side javascript environment. It includes a scheduler layered on top of Javascript's single-threaded architecture to make it seem asynchronous and reentrant (i.e. make it possible for a Javascript program to handle multiple network requests simultaneously rather than one at a time), libraries for disk, operating system, and low-level network access, and the require function (inherited from the CommonJS standard) to break a program into modules stored in separate files (think import in Java or Python, or #include in C/C++). Note that, although require is still widely used, ES2015 added an import directive to Javascript that offers certain optimization advantages and also works in browsers.

2009-era Javascript is a terrible choice for server-side development, but Node.js caught on anyway. As time went on, it has gained features and scope, making it an indispensable part of web application development.

  • Node.js incorporates an entire build environment, comparable in scope to makefiles or an eclipse project, but built in javascript and tailored to web development.
  • Most large frameworks, including Vue, React, and Angular, rely on Node.js as their build/development environment. One of the main reasons for this is to be able to break a client application into many separate files that get clumped together for distribution to the client.
  • A large ecosystem of libraries and modules is now available via Node.js's npm package manager. npm is to Node.js what pip is to Python, apt and rpm are to Linux, and the App Store is to iOS.
  • Node.js modules don't just supply code libraries for you application, they can also plug into the build process. Two such plugins that are nearly indispensable are Webpack and Babel. Webpack smushes all your client-side code into one big file to keep web browsers happy; along the way it also eliminates any unused code. Babel is a compiler that converts various formats--notably TypeScript, JSX, and Javascript itself--into Javascript. Along the way it can "minify" your code (i.e. get rid of all wide space and make variable and function names as short as possible so your code is both compact and totally unreadable), and convert instrument your code with "polyfills" to be compatible with older browsers.

In short, Node.js has become the de facto build environment for client-side web development, whether or not you also use it for the server. Rather than inflict yet another language on you in this class, we'll therefore use Node.js for the server as well.


Express

The simplest way to implement the server side of a web application is with Node.js's Express module. At a basic level, an Express application lists a bunch of URL endpoints (e.g. "/login") and associated functions. When a browser accesses a URL, Express calls the associated function rather than serving up a file on disk. It also has a concept of "middleware," which is just a way of chaining functions together. Typically, middleware will take a request, fiddle with it, then pass it on to the next function in the chain. The last one will produce the final response. Passport.js is an example of Express middleware to provide authentication services. It takes the initial request, checks if the user is authenticated, gives the user a login page if necessary, then passes the request on once authentication is complete. If authentication fails, it returns an error without passing the request on. As a result, you can write your handler to assume the user is already fully authenticated.

Clone this wiki locally