Introduction Yes, JavaScript has indeed escaped the confinement of the browser, and is now available as a scripting language that works somewhat like Ruby or Python. You write applications as JavaScript files, and run them using Node.js which includes libraries for some common tasks. Often programming languages are designed to be general purpose and then get embedded as the scripting language for an application. For instance Python scripts can be used to control parts of Maya, a popular 3D design application. JavaScript has taken the reverse approach! JavaScript was designed from the beginning to be a scripting language for the browser. It was confined within the browser, and only had access to modify the web page loaded in the browser. As browsers have become more powerful JavaScript has become more central to our idea of the web. Today running a browser with JavaScript disabled is no longer a viable option. Full complex web applications such as image edition, word processors and more have been built in JavaScript. Even so there are limitation to what JavaScript can do withing a web page, and for good reason! However, this is not a restriction of the language itself, but rather the environment (the browser) in which it runs. Node.js provides an
alternate environment for JavaScript to run in. It builds upon the V8 engine from Google’s Chrome browser, and provides a runtime for it that makes JavaScript applications viable. Node.js isn’t the only runtime to allow running JavaScript outside the browser, neither was it the first. It is however the most popular JavaScript runtime developing JavaScript applications thanks to its extensive and powerful API, and the growing ecosystem of libraries, modules and packages around it. As a developer today, it is impossible to avoid JavaScript. It is one of the most popular programming languages in the world. JavaScript is the only language that all major web browsers understand. If you develop client-side applications for the web, you’re already invested in JavaScript, it isn’t a stretch to use it on the sever side as well. By using JavaScript on both the client and server it becomes trivial to share pieces of code that are common to both (such as form validation). If you’re familiar with JavaScript, Node.js is just a stone-throw away. The language is the same, so all you need to learn are some of the conventions and features of the Node.js environment. Getting Up and Running with Node.js Getting a Node.js running on your OS is quite a simple matter. All you need to do is visit the Node.js website, nodejs.org and download the latest version for your OS. You’re likely to see two versions available, an LTS version for people who want long-term support. You’re better off with the Stable version; it has the latest features. Linux user might find their distro’s package repositories have a rather old version. The Node.js website offers Linux users tar packages that you can just extract and run. Mac and Linux users can look into nvm or Node Version Manger that helps you keep your Node.js version up to date. Once it’s installed, you can type node at your command prompt to get a JavaScript REPL. So go ahead and try the obligatory “Hello World” program; type: > console.log(“Hello World”); You should see “Hello World” printed on the console, but you will also notice that Node.js prints out undefined after that. This is expected behaviour since Node.js will print the result of whatever code you type. If you typed 2 + 2 you’d see the result 4 printed at the console. The console.log function returns nothing and as such you see undefined. If you end up doing something interesting in the REPL, you can save the code you’ve run using .save filename.js and later load it using .load filename.js Modular JavaScript Any serious application is likely to be spread across multiple files that each focus on a single aspect of the program. As such any serious programming language needs some form of module system that allows you to break down a large application into smaller pieces and put it together in some way. Unfortunately JavaScript doesn’t have a module system because of its origin as a browser-only language. Node.js has had to create its own system of modules that allows one JavaScript file to directly reference another, and to pull variables, and functions from it. There is a module system that is being standardised for JavaScript, and it isn’t too hard to pick up once you are familiar with Node.js. Let’s say we want to create a simple program that inputs a user’s name and outputs it in upper case; for this app we need some way to read user input. For our purpose we can use the inbuilt module ‘readline’ which provides this functionality, and we can get access it by setting a variable to require(‘readline’). The ‘readline’ functionality can now be accessed though this variable. Here is the code in question: const readline = require(‘readline’); const rl = readline.createInterface({ input: process.stdin, output: process.stdout}); rl.question(‘name: ‘, (answer) => { console.log(answer.toUpperCase()); rl.close();}); To run this code, put it in a file with the .js extension, and then run it as node mycode.js. Like other scripting languages, Node.js comes with its own standard library. Given its focus on server-side applications, the functionality provided by Node.js is skewed towards the requirements of a web service. Of course you are not limited to the libraries that Node.js ships with, there is an entire ecosystem of packages available for Node. js that is just a single command away. Node Packages Just like Ruby has gem, and Python has pip to install packages from a repository, Node.js has npm. Hundreds of thousands of packages are just a single command away. Just run npm install package_name in the directory of your project and you will be able to import its code and use it in your project. ASIDE: While it may seem most obvious, npm does not, in fact, stand for Node Package Manager. By default npm installs packages into a folder called node_modules in the directory in which you run it. This allows only code contained within this directory to use these modules. For some kinds of packages, such as command line tools it can be useful or even necessary to install them globally by adding a –global parameter. For instance Microsoft’s command-line tool for managing their Azure cloud computing service can be installed with npm install –global azure-cli, after which it will be available to run as azure like any other command line tool. Creating your own package is very simple with Node.js. Run npm init in the directory in which you want to initialise your project, and answer the questions it asks. This will create a package. json file in the folder. You can modify this file to your liking using any text editor. Among other things this file lets you list all the other modules your code depends on, and the version of that package you need. You can create these entries manually or, add the –save parameter while installing to automatically install the package and add it as a dependency to the package.json file. This file can also list dependencies on other modules that might be needed only during development. For instance you might need JavaScript linting and testing tools like eslint and mocha while developing your application, but they aren’t needed to run it. These can be installed using –save-dev instead of –save. If a folder has a package.json file in it, you can install all the dependencies it lists by simply running npm install in that folder. hese packages can also all be upgraded using npm upgrade. These upgrades always ensure not to upgrade to a version that might not by compatible any more. Modular JavaScript You’ll notice quickly that the Node.js community errs towards more modularity rather than less. Case in point, the popular lodash JavaScript library is composed of hundreds of useful functions, and each one is available as a separate package if it is all you need. One of the packages for instance is ‘lodash.gte’ which is a package composed of a single function that compares two values and tells you if the first is greater than or equal to the second! It is not uncommon for a single package to depend on dozens of other small packages. To ensure that a single package doesn’t bring down your entire running application by breaking something in an update, npm takes version numbers very seriously. Node.js packages need to follow the SemVer (Semantic Versioning) standard for version numbers that dictates rules for assigning version numbers to your code based on what’s changed. A version number has three parts x.y.z where x is the major version number, y the minor and z the path number. Which number should be incremented depends on how the changes made to the code in a package will affect other packages that depend on it.
The npm init command walks you through creating a basic package.json file, and you can take it from there. For instance, if there is a minor fix to a package that fixes a bug, or clarifies some documentation or otherwise makes changes that have no effect on its public API, then the patch version is to be incremented. A change that adds features, but in a way that doesn’t affect existing uses of the API will increment the minor version number. Finally any change that can break existing code using the public API should increment the major version number. Since version numbers a generally dependable, npm allow you to specify what kinds of upgrades you are OK which for which package. ASIDE: SemVer only has to do with the effect of the changes you make to your package. So if you make a necessary bug fix that unfortunately breaks some existing applications, it should come with a new major version! Once you have installed a package, you can import a package to use in your code using require(‘package_ name’) syntax to access the package functionality, similarly to how you’d access a core library. If you have multiple JavaScript files in your project you can use this syntax with the path to a file in your project to include that code. For instance const Button = require(‘./components/ Button’) will load the file Button.js in the components directory.