Skip to Content
Technical Articles

CloudFoundryFun #6 – Run TypeScript Apps on Cloud Foundry

In this sixth post in my CloudFoundryFun series, I will show how to code with TypeScript. You will learn about TypeScript and tools that can help you to use TypeScript in your daily development and deployment activities.

What is TypeScript?

I recently found this medium post that lists alternatives to JavaScript, one of which is TypeScript. While there is some truth to this, I wouldn’t call TypeScript an alternative per se. TypeScript is a superset of JavaScript. This means that all valid JavaScript code is also valid TypeScript code. One of the nice features of TypeScript is that it brings new ECMAScript features to “older legacy environments”. So you can make use of promises, iterators or template strings in your code and still run it on an older browser. This conversion of the TypeScript (.ts) files into regular JavaScript (.js) files is done by the TypeScript cross-compiler . These generated files will then comply with a specified ECMAScript specification. TypeScript is an open-source programming language which has been developed by Microsoft, but the code is can be inspected by anyone on GitHub.

These aspects are nice properties of TypeScript, but neither of them is the main motivation behind TypeScript. It’s a typed version of JavaScript, hence the name of TypeScript. Let’s look at the most common JS errors to understand why this is important.

The company Rollbar sells products for error monitoring and debugging. This allows them to collect a lot of information about programs logs, and they are also about JavaScript errors. After analyzing this data, they published the following list of the Top 10 JavaScript errors:

The chart is taken from i-programmer.info

The largest cluster of these errors could be named “Type Errors” which are direct consequences of JavaScript’s dynamically typed nature. This ranking only considers fatal errors which caused JavaScript applications to crash. It doesn’t include normal bugs which are caused by the loosely typed nature of JavaScript.

Another nice artifact of the dynamic typing of JavaScipt

Avoiding these error sources is the big claim that TypeScript makes. It uses strong typing to enforce the correct data structure types. This provides hints to developers early to type errors in their code.

I could write an entire blog post about these types of errors and strong vs loosely (or dynamic) typing, but luckily there is already a dedicated Wikipedia article about it. Also, Martin Fowler already covered this topic in 2005 and I don’t think much changed since then. At the end of the day, I don’t want to evangelize either of them. This is a decision everyone has to make for him-/herself!

Maybe you are currently in two minds: You like the ecosystem and agility of Node.js, but you also miss the static typing of other languages like Java? Then you’ll probably love TypeScript. In the next sections of this blog post, I will show you how you can develop with TypeScript and how to deploy it to Cloud Foundry environments.

Checking Types with TypeScript

Here is a simple example which demonstrates how TypeScript works.

function greeter(person: string) {
    return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);

The sample was taken from typescriptlang.org

This snippet defines a function which accepts one parameter of type string. So far, everything works fine. Now, we want to add the following piece of code below.

let user2 = [18, 60];

document.body.innerHTML = greeter(user2);

This will cause an error as the array user is clearly not a string. This error could be detected at design time, but vanilla JavaScript wouldn’t complain. And TypeScript doesn’t stop here, you can also use it to define interfaces, classes, and modifiers as shown here.

class Student {
    fullName: string;
    constructor(public firstName: string, public middleInitial: string, public lastName: string) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);

The sample was taken from typescriptlang.org

I don’t want to go deeper into TypeScript at this point. If you want to learn more about TypeScript, I highly recommend this online book.

How do I run TypeScript on Cloud Foundry?

You might think that there is a special buildpack for TypeScript, but there isn’t. Actually, you won’t run TypeScript code on any platform directly (there’s one exception). As mentioned above, TypeScript code will be cross-compiled to vanilla JavaScript code. All the advantages of TypeScript that I mentioned above are “design time features”. What I mean by that is, that all these errors can be identified while you write the code. The type checking will be performed when your code in the editor or whenever you trigger the TypeScript compiler TSC. You probably guessed it, you run the generated JavaScript code on Cloud Foundry.

This makes the JavaScript code an ephemeral artifact, as it can be generated and overwritten at any point in time. It wouldn’t make sense a lot of sense to check these files into your Git repositories. You could also say the JavaScript code of TypeScript projects can be compared to the minified JavaScript bundles of your UI projects (you typically store them in a directory named “dist” or “build”).

Develop cloud applications with TypeScript

Running the JavaScript code which has been generated by the compiler doesn’t deviate from running JavaScript code that you’ve written directly. The TSC tool can be used from the command line and offers a rich set of functionality. The disadvantage that comes with TypeScript is the overhead cost of integrating another tool into your routines. Let’s see if we can integrate this tool in our regular Cloud Foundry development tools!

Local development

Install Typescript

This first step to getting started with TypeScript is to install the library itself. The second command should verify that the installation completed successfully.

npm install -g typescript
tsc -v

Now you can start creating your first project!

Make your editor aware of the used libraries

Your IDE or editor will most likely know the TypeScript syntax and check your .ts files against it. What your IDE won’t know is the types of the used libraries, as shown in this screenshot (mind the import statement of TypeScript here).

You can make the IDE aware of these types by installing so-called declaration files.

npm install --save-dev @types/node @types/express

 

Use Watchers

As easy as invoking the TypeScript compiler is, you will get tired of this pretty soon when you’re coding. This is why I would like to recommend nodemon to listen to file changes, which trigger the compiler and restart your application.

More tools

I only listed the tools that are necessary for a small hello world sample here. There are plenty of other tools like eslint (to check your coding style) you might want to use.

Check out this hello world web server app if you want to write your first TypeScript app and to see the mentioned tools in action!

Deployments to Cloud Foundry

The naïve approach to invoke TSC and deploy the JavaScript files is pretty straight forward and doesn’t require a lot of background knowledge. The downside of this simple approach is that you always have to execute these commands in this specific order, and it doesn’t scale well when you want to add additional command line tools. In the end, you only want to package your project as a deployable unit (the mtar archive). It should be possible to integrate the TypeScript compiler into your build process to reduce the required work to one single command. This is why the mta.yaml project descriptor allows you to bring custom builders (the default builder for Node.js-based projects is npm install and the one for Java-based projects is mvn compile).

In the case of TypeScript, we can add a custom builder (compromised of two commands) to the project descriptor mta.yaml. The first one is the npm install command to make sure that all dependencies will be packaged in the deployment archive. Next, we can invoke the TypeScript compiler TSC to generate the JavaScript code file.

ID: webservice
_schema-version: "2.1"
version: 0.0.1
modules:
  - name: ts_server
    type: nodejs
    path: .
    build-parameters:
      builder: custom
      commands:
        - npm install
        - npm run build
    parameters:
      disk-quota: 256M
      memory: 256M

Whereby the npm scripts could look as follows

"scripts": {
    "clean": "rimraf dist/*",
    "copy-assets": "ts-node tools/copyAssets",
    "lint": "tslint -c tslint.json -p tsconfig.json --fix",
    "tsc": "tsc",
    "build": "npm-run-all clean lint tsc copy-assets",
    "dev:start": "npm-run-all build start",
    "dev": "nodemon --watch src -e ts,ejs --exec npm run dev:start",
    "start": "node ."
},

Once you packaged the archive, you can follow the same procedure to deploy it to Cloud Foundry as always (you need to have the build tool installed).

mbt build -p=cf
cf deploy mta_archives/webservice_0.0.1.mtar

I chose TypeScript for this post as I personally think, this language is especially interesting for enterprise developers. In general, it’s worth noticing that customer builders can be used for any project type and build tasks. You can also trigger Maven builds for Java-based projects or any other build tool via shell commands.

Do you already have more ideas about how you could adapt the build step to your individual project needs? Let me know in the comments!

Summary

In this edition you have learned:

  • That the most common JavaScript errors are type-based
  • What TypeScript is and how it works
  • How to use TypeScript type declaration files
  • How to integrate the TypeScript compiler into the MTA build process
  • About other use cases for the custom builder

About this series

This was the sixth blog post of my monthly series #CloudFoundryFun. The name already says all there is to it, this series won’t be about building enterprise apps on Cloud Foundry. I think there are already plenty of great posts about those aspects out there. This series rather thinks outside the box and demonstrates unconventional Cloud Foundry use-cases.

CloudFoundryFun #7 – Connect VS Code to deployed cloud applications

Be the first to leave a comment
You must be Logged on to comment or reply to a post.