AWS CodeStar and TypeScript - Part 3

Reading time ~4 minutes

In this post you’ll see how to get the TypeScript portion of the project working. The setup mostly involves standard TypeScript setup and then a few AWS specific additions for the build and deploy steps.

TypeScript Configuration

The first thing to do is to get the application building locally.

tsconfig.json

{
  "compilerOptions": {
    "target": "ES5",
    "module": "commonjs",
    "noEmitOnError": true,
    "noImplicitAny": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "sourceMap": true
  }
}

This is pretty vanilla TypeScript configuration file. The target is ES5 and the module loader is commonjs.

gulpfile.js

var gulp = require('gulp');
var ts = require('gulp-typescript');
var path = require('path');
var sourcemaps = require('gulp-sourcemaps');

gulp.task('build:server', function() {
    var tsProject = ts.createProject(path.resolve('./tsconfig.json'));
    var tsResult = gulp.src([
        '**/*.ts',
        '!node_modules/**/*.ts'
    ])
        .pipe(sourcemaps.init())
        .pipe(tsProject())
    return tsResult.js
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(path.resolve('.')))
});

gulp.task('build', ['build:server']);

gulp.task('default', ['build']);

I use gulp to build the TypeScript files and use the gulpfile.js to tell gulp which files to compile. Like the tsconfig.json, pretty standard stuff. I want to compile any *.ts files except those in node_modules.

npm setup commands

npm install gulp -g --save-dev
npm install gulp
npm install gulp-typescript --save-dev
npm install gulp-sourcemaps --save-dev
npm install typescript --save-dev

To be able to build using TypeScript you need to install several npm packages. The order doesn’t really matter, but first I install gulp (for reasons unknown to me I need to run with the -g –save-dev options and then do it again without any options). Next, I install gulp-typescript, gulp-sourcemaps, and typescript all with the –save-dev option because they are only needed to compile the TypeScript files and aren’t needed at runtime.

.gitignore

.DS_Store
node_modules
typings
**/*.js
npm-debug.log
!gulpfile.js

I added a .gitignore file to prevent git from tracking non-source files. Since this is a TypeScript project I actually don’t want to track any .js file thus the */.js. One exception is the gulpfile.js which leads to the !gulpfile.js

TypeScript Code

With the setup out of the way here is the actual code for the project.

index.ts

import * as awsServerlessExpress from 'aws-serverless-express'
import {ServerApp} from './serverApp' 
var serverApp = new ServerApp();
var server = awsServerlessExpress.createServer(serverApp.getApp());

exports.handler = (event: any, context: any) => awsServerlessExpress.proxy(server, event, context);

index.ts is the main entry point for the AWS Lambda function. aws-serverless-express needs to be imported and acts as the glue between the Express application and th Lambda function. The ServerApp module is imported and does the actual handling of requests; is is wrapped by aws-serverless-express by using the awsServerlessExpress.createServer() function call. Finally the AWS Lambda handler is exposed by the exports.handler assignment.

serverApp.ts

import * as express from 'express';

export class ServerApp {
    private app: express.Application;

    constructor() {
        this.app = express();

        this.configureApp();

        this.setRoutes();
    }

    private configureApp() {
    }

    public setRoutes() {
        this.app.get('/', function(req: express.Request, res: express.Response) {
            res.send({
                "Output": "Typescript Hello World!"
            });
        });

        this.app.post('/', function(req: express.Request, res: express.Response) {
            res.send({
                "Output": "Hello World!"
            });
        });
    }

    public getApp() {
        return this.app;
    }
}

ServerApp is a very basic Express application. The constructor has a call to configureApp() where future app configuration can occur, and it also makes a call to setRoutes() which will configure the routes for the application. This implementation of the routes is very basic for now just to get things up and running and to verify that the TypeScript code is being used and not the JavaScript from the template source.

npm express commands

npm install express --save
npm install --save @types/express
npm install aws-serverless-express --save
npm install --save @types/aws-serverless-express
gulp build

Now that we have the TypeScript code in place we need to add a few npm packages to get it to build. We need to install the express and aws-serverless-express modules and we need to install the corresponding TypeScript types. We can then run gulp build to compile the TypeScript files.

buildspec.yml

version: 0.1

phases:
  build:
    commands:
      - npm install
      - npm install gulp -g --save-dev
      - npm install gulp
      - npm install gulp-typescript --save-dev
      - npm install gulp-sourcemaps --save-dev
      - npm install typescript --save-dev
      - npm install express --save
      - npm install --save @types/express
      - npm install aws-serverless-express --save
      - npm install --save @types/aws-serverless-express
      - gulp build
      - aws cloudformation package --template template.yml --s3-bucket $S3_BUCKET --output-template template-export.json
artifacts:
  type: zip
  files:
    - template-export.json

To get this building in the CodeDeploy environment on AWS we need to update the buildspec.yml. We simply insert the same commands we used to setup the local environment to the buildspec.yml after the - npm install command.

Wrap Up

We now have a basic Express application written in TypeScript that is built and deployed on AWS. You are free to build your own application from this foundation. In future posts I will be adding functionality to this application which will include additional HTTP endpoints, connecting to an RDS instance, integrating with Auth0, and configuring the same application to be able to run locally to reduce the time needed for application development.

Perils of a Family-First Software Developer

I've just survived a RIF, my skills and tool set are built around technologies that were modern 10 years ago, my interviewing skills have...… Continue reading

AWS CodeStar and TypeScript - Part 2

Published on May 17, 2017

AWS CodeStar and TypeScript - Part 1

Published on May 16, 2017