When I think back 10 years or so when I was writing code for a monolithic codebase written in C++, one of the worst memories I have of the time was waiting for a build to complete just to run a couple lines of new code. The pain was so common among engineers that it bore the creation of one of the all-time most popular XKCD comics:

This is a great idea, if executed safely.

My office at the time didn't have swords to play with, so waiting for a build to complete was really boring.

The pain is similar if I had to deploy my Cloud Functions code every time I want test a function. Fortunately, the Firebase CLI now has a local emulator that works for both HTTPS and other types of functions. This lets me run the functions on my development machine by emulating the events that would trigger it. You can read more about that in the documentation.

One of the emulator's handy features is the fact that it will reload any JavaScript files that change over time. So, if you modify the code of a function, you can test it right away in the emulator without having to restart it:

  1. Switch to code editor, write JavaScript
  2. Switch to emulator, run code
  3. GOTO 1

It's fast and easy, and keeps you "in the zone".

However, things become less easy when you switch from JavaScript to TypeScript. Running TypeScript on Cloud Functions requires a compilation phase to convert the TypeScript into JavaScript so that it can be executed by the emulator. It adds a bit of a hassle:

  1. Switch to code editor, write TypeScript
  2. Switch to command prompt, execute npm run build to generate JavaScript
  3. Switch to emulator, run code
  4. GOTO 1

There's an easier way to do this that doesn't involve running a command every time. The TypeScript compiler (tsc) has a special "watch mode" that lets it pick up changes to your TypeScript and automatically compile them. You can run it from the command line by changing to your functions folder and running this command:

./node_modules/.bin/tsc --watch

With this running alongside the local emulator, which automatically picks up changes to the compiled JavaScript, your development workflow goes back to this:

  1. Switch to code editor, write TypeScript
  2. Switch to emulator, run code
  3. GOTO 1

And, if you're using VSCode, you can even have it directly run tsc in watch mode. You can start it up with Tasks -> Run Build Task..., then choosing "tsc: watch".

It will fire up a command shell right in the IDE, run tsc --watch, and show you the output. You'll see messages like this, along with any compilation errors, any time a TypeScript file changes:

2:38:38 PM - File change detected. Starting incremental compilation...
2:38:38 PM - Compilation complete. Watching for file changes.

Now, bear in mind that tsc in watch mode won't run TSLint against your code, so be sure to set that up in VSCode so you can always see its recommendations, as I showed in a prior blog post. If you're not linting your code, seriously consider setting that up, because you'll catch potential mistakes that could be costly in production.