Node.js - tutorial - REPL

revision:


what is REPL?

REPL stands for Read Eval Print Loop and it represents a computer environment like a Windows console.

When a command is entered, the system responds with an output in an interactive mode. Node.js or Node comes bundled with a REPL environment. It performs the following tasks:

Read − reads user's input, parses the input into JavaScript data-structure, and stores in memory.
Eval − takes and evaluates the data structure.
Print − prints the result.
Loop − loops the above command until the user presses ctrl-c twice.


how to use the Node.js REPL

The node command is the one we use to run our Node.js scripts

example

node script.js

If we omit the filename, we use it in REPL mode.

example

 >node
        >

The command stays in idle mode and the REPL waits for us to enter some JavaScript code.

example

> console.log('test')
        test
        undefined
        >

The cool thing about the REPL is that it's interactive. As you write your code, if you press the tab key the REPL will try to autocomplete what you wrote to match a variable you already defined or a predefined one.

example

Try entering the name of a JavaScript class, like Number, add a dot and press tab.The REPL will print all the properties and methods you can access on that class.

You can inspect the globals you have access to by typing global. and pressing tab.

If after some code you type _ (i.e. underscore), that is going to print the result of the last operation.

The REPL has some special commands, all starting with a dot. They are

.help: shows the dot commands help;
.editor: enables editor mode, to write multiline JavaScript code with ease; once you are in this mode, enter ctrl-D to run the code you wrote;
.break: when inputting a multi-line expression, entering the .break command will abort further input; same as pressing ctrl-C.
.clear: resets the REPL context to an empty object and clears any multi-line expression currently being input;
.load: loads a JavaScript file, relative to the current working directory;
.save: saves all you entered in the REPL session to a file (specify the filename);
.exit: exits the REPL (same as pressing ctrl-C two times).


Node.js accept arguments from the command line

You can pass any number of arguments when invoking a Node.js application using "node app.js". Arguments can be standalone or have a key and a value.

example

node app.js joe
node app.js name=joe

This changes how you will retrieve this value in the Node.js code. The way you retrieve it is using the process object built into Node.js. It exposes an argv property, which is an array that contains all the command line invocation arguments.
- The first element is the full path of the node command.
- The second element is the full path of the file being executed.
- All the additional arguments are present from the third position going forward.
- You can iterate over all the arguments (including the node path and the file path) using a loop.

example

process.argv.forEach((val, index) => {
    console.log(`${index}: ${val}`)
  })

You can get only the additional arguments by creating a new array that excludes the first 2 params: "const args = process.argv.slice(2)".If you have one argument without an index name, like this "node app.js joe", you can access it using "const args=process.argv.slice(2) args[0]".


output to the command line using Node.js

Node.js provides a console module, which provides tons of very useful ways to interact with the command line. It is basically the same as the console object you find in the browser.

The most basic and most used method is console.log(), which prints the string you pass to it to the console. If you pass an object, it will render it as a string.

You can pass multiple variables to console.log.

example

JS: 
    const x = 'x'
    const y = 'y'
    console.log(x, y)
  

We can also format pretty phrases by passing variables and a format specifier.

example

JS:
    console.log('My %s has %d years', 'cat', 2)
  

%s format a variable as a string;
%d format a variable as a number;
%i format a variable as its integer part only;
%o format a variable as an object.

console.clear() clears the console (the behavior might depend on the console used)

console.count() will count the number of times a string is printed, and print the count next to it.

The console.countReset() method resets counter used with console.count().

There might be cases where it's useful to print the call stack trace of a function. You can do so using console.trace().

You can easily calculate how much time a function takes to run, using time() and timeEnd().

console.log is great for printing messages in the Console. This is what's called the standard output, or stdout.

console.error prints to the stderr stream. It will not appear in the console, but it will appear in the error log.

You can color the output of your text in the console by using escape sequences. An escape sequence is a set of characters that identifies a color.

example

console.log('\x1b[33m%s\x1b[0m', 'hi!')

However, this is the low-level way to do this. The simplest way to go about coloring the console output is by using a library. Chalk is such a library, and in addition to coloring it also helps with other styling facilities, like making text bold, italic or underlined. You install it with npm install chalk, then you can use it

example

  const chalk = require('chalk')
  console.log(chalk.yellow('hi!'))
 

Progress is an awesome package to create a progress bar in the console. Install it using npm install progress.

example

JS:
  const ProgressBar = require('progress')

  const bar = new ProgressBar(':bar', { total: 10 })
  const timer = setInterval(() => {
    bar.tick()
    if (bar.complete) {
      clearInterval(timer)
    }
  }, 100)
 

accept input from the command line in Node.js

Node.js since version 7 provides the readline module to perform exactly this: get input from a readable stream such as the process.stdin stream, which during the execution of a Node.js program is the terminal input, one line at a time.

example

JS:
    const readline = require('readline').createInterface({
      input: process.stdin,
      output: process.stdout
    })
    
    readline.question(`What's your name?`, name => {
      console.log(`Hi ${name}!`)
      readline.close()
    })
 

This piece of code asks the username, and once the text is entered and the user presses enter, we send a greeting. The question() method shows the first parameter (a question) and waits for the user input. It calls the callback function once enter is pressed. In this callback function, we close the readline interface.

A more complete and abstract solution is provided by the Inquirer.js package. You can install it using npm install inquirer. Inquirer.js let you do many things like asking multiple choices, having radio buttons, confirmations, and more. It's worth knowing all the alternatives, especially the built-in ones provided by Node.js, but if you plan to take CLI input to the next level, Inquirer.js is an optimal choice.


expose functionality from a Node.js file using exports

Node.js has a built-in module system. A Node.js file can import functionality exposed by other Node.js files. When you want to import something you use const library = require('./library') to import the functionality exposed in the library.js file that resides in the current file folder. In this file, functionality must be exposed before it can be imported by other files. Any other object or variable defined in the file by default is private and not exposed to the outer world.

This is what the module.exports API offered by the module system allows us to do. When you assign an object or a function as a new exports property, that is the thing that's being exposed, and as such, it can be imported in other parts of your app, or in other apps as well.

You can do so in 2 ways.

The first is to assign an object to module.exports, which is an object provided out of the box by the module system, and this will make your file export just that object.

example

JS:
    // car.js
    const car = {
      brand: 'Ford',
      model: 'Fiesta'
    }
    module.exports = car

    // index.js
    const car = require('./car')
  

The second way is to add the exported object as a property of exports. This way allows you to export multiple objects, functions or data.

example

JS:
    const car = {
      brand: 'Ford',
      model: 'Fiesta'
    }
    
    exports.car = car
  

or directly

JS:
    exports.car = {
      brand: 'Ford',
      model: 'Fiesta'
    }
  

And in the other file, you'll use it by referencing a property of your import.

example

JS:
    const items = require('./items')
    const car = items.car
  

or

JS:
    const car = require('./items').car