Project

General

Profile

Using developer mode

Developer mode is a trick to keep HouseMon (or any other app based on JeeBus) running in such a way that source files get recompiled and reloaded whenever they change on disk.

Changes to *.go files cause the HouseMon server to be recompiled, while changes to CoffeeScript, Jade, or Stylus files cause the files to be translated into JavaScript, HTML, or CSS, respectively - followed by an automatic reload of the browser, which will then pick up the resulting changes.

Developer mode can speed up the “edit/run” cycle considerably for client-server apps such as HouseMon.

The setup

To make this work, node.js must be installed - even though it’s not being used as server.

The reason is that node.js is still needed to translate .coffee, .jade, and .styl files into a format which can be used in the browser. And since node.js is used to watch these files in the background anyway, it is also set up to detect the .go file changes and recompile the server.

Apart from installing node.js, there should be an index.js file in the HouseMon directory, containing:

require(‘./common/devmode’);

This reduces typing later and assumes that the file common/devmode.js exists, for doing the real work.

Starting in developer mode

Easy - just enter this command in the HouseMon directory:

node .

Node the dot at the end! This is actually shorthand for node ./index.js.

What happens next

Node.js processes the devmode.js script to perform a number of tasks:

  • run the npm command to install node.js dependencies (this is only done once)
  • start watching the ./app, ./base, ./common, and ./gadgets directories
  • compile and launch HouseMon, by performing go get *.go

That’s it. As long as no source file changes are detected, HouseMon will run in exactly the same way as if it had been compiled and started manually.

When a change to source files is detected, different things can happen, depending on the type of file:

  • CoffeeScript, Jade, and Stylus sources are translated and saved to disk
  • JavaScript and HTML changes generate a page reload in the browser
  • CSS changes trigger a stylesheet reload request in the browser

Under the hood

All the work is done in the devmode.js script, which is in fact itself a translated version of the devmode.coffee source file.

Go compilation is performed by spawning a go run *.go process, which not only compiles the code, but also starts the resulting binary if all went well. In the case of a compiler error, go and node.js will both exit.

CoffeeScript, Jade, and Stylus compilation is done as usual, by packages installed specifically for that task by npm. Note that CoffeeScript files are compiled with "source maps", inlined by the convert-source-map package. This has the incredibly convenient side-effect that errors in the browser will refer to lines in the CoffeeScript source code, not the translated JavaScript!

Live reload

The reload mechanism requires some special conventions between node.js and HouseMon: first of all, the HouseMon app must send its process ID (pid) to stdin (!) on startup, as this is the only way for node.js to find out which process it needs to kill for recompiles.

In node.js, stdin is set up as "ipc" channel, which allows sending JSON messages in both directions. To force a page reload, the value "true" is sent. To trigger a stylesheet reload, the value "false" is sent.

HouseMon in turn, needs to keep a goroutine running to watch stdin. Whenever a message is received, it must broadcast that message on all currently-connected websockets.