When we are doing a NodeSchool or a Node.js/Microservices training we usually run into participants who feel lost when they have to use the terminal. Because of this we decided to do a mini blog series of two posts of using the terminal for Node.js development: one dealing with the very basics, and one with more advanced, in-depth tips and tricks.

Terminal Basics

Disclaimer: I'm using the word terminal here because I don't mean a particular shell, but a whole collection of shells.

Just to be clear: In computing, a shell is a user interface for access to an operating system's services.

The terminal is your universal Swiss Army knife, it will be always with you wherever you go, even if you're working on a remote server or a local machine.

The terminal is a computer console, a text output device for system administration messages.

Having text input has been always a part of the computer since the beginning of time, but since then we have changed for so called user-friendly interfaces that are much easier to use.

But are you sure that those are more efficient?

A text-based input and output is mandatory for building good software:

Write programs to handle text streams, because that is a universal interface.

Having a blinking cursor can be too scary at first for many, but when you get into using it, it will be as simple as any other program.

Here's a picture of my setup:

Peteyy's terminal setup for NodeJS development

That's not that bad, is it?

But this post is not about how fancy it could be, but rather what can you accomplish using it. There are a few tools that if you integrate into your workflow you will definitely become a more productive programmer.

Without further due, let's begin! These tools are must have, if you'd like to work with the command line.

MAN pages

Read the manual. Man pages are used for documenting CLI applications. Be sure to get familiar with them if you want to dive into using a console interface.

Simply type:

man program_name

You can navigate with the arrow or h, j, k, l keys and quit with q. Searches can be performed starting with a / and after that the search query.

Bash

Shell knowledge comes handy almost every day; the basic commands are the following, if you'd like to know how to use them try out their man pages.
(eg. man cd)

  • cd
  • ls
  • cp
  • rm
  • mv

When opening Finder on OSX and clicking through the folders finding a way through them and dragging and dropping is slow. Admit it you feel it every time, there must be a better way. If you know these simple commands and their various switches, you will eventually become more productive.

For more advanced users there is also:

  • find
  • grep
  • sed

These can speed up file-related operations searching and replacing. With a modern editor that can be easily accomplished but for insane RegEx patterns sometimes its better to pull out grep (or any alternative these days: ack, ag or fzf) and use that. And also that's a nice show-off you can do at the office when pulling off a sweet search and replace by a crazy RegEx command.

Nodemon

This is a tool I always use to manage my node processes during development. With nodemon you can start a node process and it keeps it running for. It utilizes fsevents to hook into filesystem changes and it restarts the node process on each file change.

You can specify the configuration in the nodemon.json file which looks just like
this sample file:

{
  "restartable": "rs",
  "ignore": [
    ".git",
    "node_modules/**/node_modules"
  ],
  "verbose": true,
  "execMap": {
    "js": "node --harmony_destructing"
  },
  "env": {
    "NODE_ENV": "development",
    "MONGODB_URI": "mongodb://fakemongodb.io"
  },
  "ext": "js json yaml"
}

I use it for several reasons:

  • it keeps my env variables needed for development organised
  • ability to specify extensions to watch is a powerful feature
  • specify exec command for harmony flags on node v4.0.0 :)

You can pass these configurations around if you're working on the project with someone else, and they will have the same project setup without having to fiddle with the env variables.

Also make sure you keep nodemon.json in your .gitignore as you may add sensitive information to it. Better be safe than sorry.

Gulp

Gulp is a build tool that is useful if you have to manage a lot of files for a frontend application. It lets you set up a build pipeline and set up a handful of tasks that otherwise you'd have to do manually. Gulp is also available on npm and has quite a few already written plugins for you so you don't have to write all the code yourself.

As I've mentioned gulp has tasks, these tasks look something like this:

'use strict';

var gulp = require('gulp');
var stylus = require('gulp-stylus');
var sourcemaps = require('gulp-sourcemaps');

var config = require('./config');

/*
 * Style
 */
gulp.task('style', function () {
  var opts = {
    'include css': true
  };

  if (config.isProduction) {
    opts.compress = true;
  }

  return gulp.src(config.srcPath.styles)
    .pipe(sourcemaps.init())
    .pipe(stylus(opts))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('dist/styles/'));
});

To run this you just have to:

gulp style

And all these things will be done for you automagically.

This one bit right here will compile stylus code to css, minify css, and create sourcemaps for them, and copy them to a dist folder.

Having these tasks you can tell gulp what to do with your files, these can be as simple as a copy, but can also be more complex like packaging applications into an artifact.

NPM

If you'd like to work with Node, you have to get familiar with the concepts behind modular architecture. NPM is a tool that not only makes this possible for us but also makes it easy and frictionless.

If you are about to start working on a new project, just type:

npm init

npm init -y sets up a project with defaults, that is pretty useful for test projects or prototyping.

npm init -y in terminal for NodeJS developers


"Everything" is just an npm install away.

npm install package_name

npm install has a shorter alias which is npm i


In case you want to save it as a dependency use

npm install --save

If you want to install to development dependencies

npm i package_name --save-dev

For me --save-dev is way too long, use -D as an alias for --save-dev.


These are the most simple tasks that can be accomplished with npm, but this can be taken further by tinkering a bit with the package.json file.

There is a script field in the package.json file and with that you can add additional functionalities to your NPM CLI.

"scripts": {
  "test": "npm run test-server & gulp test-client",
  "coverage": "NODE_ENV=test istanbul cover _mocha -- --require co-mocha $(find server -name \"*.spec.js\"); open coverage/lcov-report/index.html",
  "test-server": "NODE_ENV=test mocha --require co-mocha $(find server -name \"*.spec.js\")",
  "test-client": "gulp test-client",
  "start": "node server/processes/web/server.js",
  "start-worker": "node server/processes/worker/index.js",
  "jshint": "jshint server",
  "jscs-server": "jscs server"
}

As seen above you can also chain these scripts together to add even more spice to it. Anything can be passed there as long as they are valid bash scripts.

Also what's great about it is that NPM looks for node_modules/.bin for executables when running these scripts - so in the example above neither jshint, nor jscs was installed globally.

Node Version Manager (NVM)

nvm in terminal for NodeJS developers

Have you tried installing multiple Node versions on your computer before? Well, I'm sure that was a pain to manage but with this small little tool it's already solved for you. nvm is a tool that let's you manage multiple node versions with a single command. Installing it is as simple as this:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.26.1/install.sh | bash

It will install nvm and put a small snippet into your .bashrc to load it every time you launch a shell.

nvm install 0.12
nvm install 4

If you install a new version nvm will automatically set that version as default if you want to alter it, use:

nvm alias default 4

If you install a new version, globally installed packages will not be available in the newly installed environment. For that you can use:

nvm install 4 --reinstall-packages-from=iojs

This way it will install all the previously installed packages on the new version as well.

bash_profile

.bash_profile or .bashrc is the file that's being read and executed upon creating new bash process when opening a terminal window. You can set up various init scripts and aliases in that file. Having aliases in your .bash_profile will eventually speed up your work process with these tools I've mentioned even more. This will save you a couple of letters when typing.

A small example would be:

set alias git=g
set alias nrtc=npm run test-client

4 letters instead of 19, once it's not much but when you have to type that every minute while working on a project on the longer run, it's totally worth it.

Tmux

tmux is a terminal multiplexer that allows you to have multiple windows and so-called 'panes' running in one terminal window. During development, I always have several windows open with one or more panes. These consist of a gulp build process for frontend, nodemon for running a server, vim for editing files, mongo-shell for interacting with the database, and I also like to run irssi for connecting to various team chats.

You can get tmux from brew or apt-get depending on the operating system. For further reading.

Integrating the terminal into your Node.js development workflow

But come on, it's a long road to learn all these things, and chances are that you already have a GUI app for these things!

At first everything may seem hard and useless but then you start grasping it, you'll create things that would be more time consuming otherwise. All of these things can be composed together to create an exciting, fast and portable workflow that will make daily coding much more enjoyable.

You can check my dotfiles on GitHub at peteyy/dotfiles.

I would not recommend you to fetch someone else's dotfiles, but find out what you want and how you can do it, and build up your own little domain that's truly yours.

Some inspiration on how to start out other than mine can be found at here: https://dotfiles.github.io/.

What do you think of this terminal setup? Let me know in the comments below.