Creating an Azure IoT Edge Typescript Module

Let's learn how we can create a Typescript module in our Azure IoT Edge project!

⚠️ At the day of writing (15/NOV/2022) the IoT Edge ecosystem is under construction, I highly recommend to follow this entire post as the current shipped Node.js version is v10 (we are currently LTS on v18)

TL;DR

You can easily copy the code from this post from my Public Repository

PublicProjects/Azure-IoT-Edge/Typescript-and-Python-Modules-Communicating/modules/AudioInferencing at master · XavierGeerinck/PublicProjects
Contribute to XavierGeerinck/PublicProjects development by creating an account on GitHub.

Prerequisites

  • A working IoT Edge solution and connected device
  • Working iotedgedev cli command
  • Basic understanding of Module development

Creating our Module

Out of the box, IoT Edge does not offer Typescript. So let's start by initializing the Nodejs boilerplate:

iotedgedev solution add --template nodejs AudioInferencing

This will initialize our project with the corresponding Docker build files and source code. Opening up the app.js file in the modules/AudioInferencing module that was created will reveal that it is all Javascript code so let's convert this to Typescript

Converting it to Typescript

In an earlier post I explained how we can initialize a Typescript project. This is the same! So, navigate to your modules/AudioInferencing module directory and run the commands

npm init -y

# Install Typescript, ts-node and nodemon
pnpm i -D typescript ts-node nodemon @types/node

# Install SWC for transpiling Typescript
pnpm i -D @swc/core @swc/helpers regenerator-runtime

# Generate TSConfig and adapt for SWC usage
npx tsc --init

# Configuring tsconfig.json
# note: we specify ./dist as output dir and ./src as input
sed -i 's%// "outDir": "./"%"outDir": "./dist"%' tsconfig.json
sed -i 's%// "rootDir": "./"%"rootDir": "./src"%' tsconfig.json

# Demo Hello World
mkdir src; echo 'console.log("Hello World");' > src/index.ts

and finally update the package.json to include our scripts:

{
    "name": "your_application",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "start": "ts-node --swc ./src/index.ts",
        "dev": "nodemon --watch './src/**/*.ts' --exec 'ts-node --swc' ./src/index.ts"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@swc/core": "^1.2.244",
        "@swc/helpers": "^0.4.11",
        "nodemon": "^2.0.19",
        "regenerator-runtime": "^0.13.9",
        "ts-node": "^10.9.1",
        "typescript": "^4.8.2"
    }
}

When we run npm run start we will see our application being ran

Updating the Dockerfile

Finally, left to do is to update the Dockerfile. Just add this code:

FROM node:current-alpine

WORKDIR /app/

# Install Package.json dependendencies
COPY package.json .
RUN npm install -g npm@latest \
    && npm -v \
    && npm install

# Copy Source Code
COPY . .

USER node

CMD ["npm", "run", "start"]

and we are set to go! Rebuild your module and deploy it to your device to get started.