It came as a bit of a shock that I have been running MagicMirror in my home office for almost two years now. I even wrote two modules, one to display Prometheus alerts and one to show Status Page status.
In the past few years I have started to become more and more comfortable with Typescript, I wanted to see if I could convert my modules to Typescript.
Finding an example
As is the case with most development, the first step was to see if someone else had done it. As it turns out, a few folks have done it.
I stumbled across Michael Scharl’s post on dev.to which covered his Typescript MagicMirror module. In the same search, I ran across a forum post by Jalibu that focused a little more on the nitty-gritty, including his contribution of the
magicmirror-module in DefinitelyTyped.
Migrating to Typescript
Ultimately, the goal was to generate the necessary module files for MagicMirror through transpilation using Rollup (see below), but first I needed to move my code and convert it to Typescript. I created a
src folder, moved my module file and node_helper into there, and changed the extension to
My modules already had a good amount of development packages around linting and formatting, so I updated all of those and added packages necessary for Typescript linting.
A Note on Typing
Originally, following Michael Scharl’s sample code, I had essentially copied the
module-types.ts file from the MagicMirror repo and renamed it
ModuleTypes.d.ts in my own code. I did not particularly like that method, as it required me to have extra code in my module, and I would have to update it as the MagicMirror types changed.
Jalibu‘s addition of the
@types/magicmirror-module package simplified things greatly. I installed the package and imported what I needed.
import * as Log from "logger";
import * as NodeHelper from "node_helper";
The package includes a
Module namespace that makes registering your module easy:
// Module implementation
A few tweaks to the
tsconfig.json file, and the
tsc command was running!
The way that MagicMirror is set up, the modules generally need the following:
- Core Module File, named after the module (
- Node Helper (
node_helper.js) that represents a Node.js backend task. It is optional, but I always seem to have one.
- CSS file, if needed. Would contain any custom styling for the HTML generated in the Core Module file.
Michael Scharl’s post detailed his use of Rollup to create these files, however, as the post is a few years old, it required a few updates. Most of it was installing the scoped rollup packages (@rollup), but I also removed the banner plugin.
I configured my Rollup in a ‘one to one’ fashion, mapping my core module file (
src/MMM-PrometheusAlerts.ts) to its output file (
MMM-PrometheusAlerts.js) and my node helper (
src/node_helper.ts) to its output file (
Taking a cue from Jalibu, I used the
umd output format for
node_helper, since it will be running on the backend, but
iife for the core module, since it will be included in the browser.
As I was looking at code that had not been touched in almost two years, I took the opportunity to update libraries. I also switched over to Jest for testing, as I am certainly more familiar with it, and I need the ability to mock to complete some of my tests. I also figured out how to implement a SASS compiler as part of rollup, so that I could generate my module CSS as well.
To make things easier on anyone who might use this module, I added a
One down, one to go
I converted MMM-PrometheusAlerts, but I need to convert MMM-StatusPageIo. Sadly, the latter may require some additional changes, since StatusPage added paging to their APIs and I am not yet in full compliance…. I’ve never had enough incidents that I needed to page. But it has been on my task list for a bit now, and moving to Typescript might give me the excuse I need to drop back in.