Making a node executable with Typescript

2017-12-17

I recently worked on a small project that could be used in our build process for bigger apps. The aim of the project was to build some executable package that could communicate with cloud foundry (PaaS) and query an apps status, this was usually in one of three states

  • STOPPED
  • STARTED
  • CRASHED

We were going to be making a lot of network requests so I thought it would be a good idea to have something that could easily map the responses of each of the requests to meaningful pre-determined interfaces, Typescript was the obvious choice. In this article id like to build a small hello world of how the this is possible.

Lets start by making a new folder, and lets call our new project "npm-typescript-executable"

mkdir npm-typescript-executable
cd npm-typescript-executable

Lets now create our package.json file with the command below

npm init -y

Npm usually asks multiple questions, so adding the -y flag will automatically provide the defaults to each prompt so we don't have to. If this command is successful you should see a new package.json file

Next up we are going to need to install our dependencies to get up and running. I'm going to be using the yarn package manager for this rather than npm. If you are unfamiliar with yarn then please checkout https://github.com/yarnpkg/yarn, there are lots of advantages to using this package manager but we are only concerned with one of the best reasons to use it and that is its speed.

If you have never installed yarn then you can do so by running the command below

npm install -g yarn

Yarn should now be installed and we can use it to install our required dependencies using the command below

yarn add ts-node typescript

You may notice a new file called "yarn.lock". Don't worry about this file as it is completely normal and is used by yarn to track dependencies.

Lets add our index.js entry point for the app. You may notice that it has an extension of .js and not .ts, this is intentional as we cannot point the bin entry in package.json to a .ts file as it is expecting a plain javascript file. Every other file will have .ts extensions. So index.js will look like

#!/usr/bin/env node

require('ts-node/register');
require('./index.ts');

The first thing you will notice is that we need a hashbang to allow node to execute the file. Next we require ts-node which enables On the fly compilation support for typescript files, finally we require our entry typescript file, in this case its called index.ts. Lets create this file now

import {awesomeStuff} from './lib/awesome-stuff';

awesomeStuff();

So this is our first typescript file and you may notice it is using the es6 import syntax, this imports a function called awesomeStuff from ./lib/awesome-stuff and executes the function. Lets take a look at the awesome-stuff.ts file. First lets create a new folder called lib

mkdir lib

and add a file called awesome-stuff.ts to the lib folder

export function awesomeStuff() {
  console.log('Doing awesome stuff');
}

This doesn't do anything particularly amazing it just console.logs a simple message. Notice the export keyword, this is necessary otherwise the import keyword wont work in the previous file above.

So now we have our two typescript files, how do we make node execute them?. We need to add a new key called bin in our package.json file like below

{
  "name": "npm-typescript-executable",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ts-node": "^3.0.2",
    "typescript": "^2.2.1"
  },
  // This is where the magic happens
  "bin": {
    "hello-typescript": "./index.js"
  }
}

If you havent noticed from the above we are going to be using the command hello-typescript to run our executable, if you try running this now it will throw an error. We need to run one final command to make this work.

npm link

now if we try running the hello-typescript command again you should get the expected outcome

D:\git\npm-typescript-executable>hello-typescript
Doing awesome stuff

Awesome stuff, You can find the code for this tutorial here - https://github.com/el-davo/npm-typescript-executable